# FastCGI PHP - unable to prematurely close connection to browser

**URL:** <https://www.ruby-forum.com/t/fastcgi-php-unable-to-prematurely-close-connection-to-browser/183027>\
**Category:** NGINX\
**Created:** [February 6, 2010, 11:01am UTC](https://www.ruby-forum.com/t/fastcgi-php-unable-to-prematurely-close-connection-to-browser/183027 "2010-02-06T11:01:36Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![cactus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/f475e1/32.png) [@cactus](https://www.ruby-forum.com/u/cactus)\
**Post date:** [February 6, 2010, 11:01am UTC](https://www.ruby-forum.com/t/fastcgi-php-unable-to-prematurely-close-connection-to-browser/183027/1 "2010-02-06T11:01:36Z")

</div>

Hi all!

I am optimizing a few of the PHP scripts by:

- doing all that generates output to browser
- closing connection to browser
- doing some more processing

The processing bit cannot be avoided, but the speed of execution (from  
visitors’ point of view) is awesome this way. The problem is that we  
have tried migrating the script to NginX + FastCGI (it works on Apache +  
mod\_php) but it doesn’t close the connection anymore, it keeps it open  
until the end… Which makes scripts slow again.

I am using Content-Length to allow server to figure out that all content  
was already generated. This is the test case:

\<? header("Connection: close"); // not sure we need this one header("Content-Encoding: none"); ignore\_user\_abort(true); ob\_start(); echo ('Lets output something.'); // output Content-Length and flush buffers: $size = ob\_get\_length(); header("Content-Length: $size"); ob\_end\_flush(); flush(); // \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* // do some heavy processing here: sleep(5); function postproc() { flush(); sleep(5); } register\_shutdown\_function('postproc'); ?\>

The browser shows this page immediately in Apache+mod\_php but it waits  
for 10 seconds in NginX + FastCGI.

I am a bit stuck here and would appreciate some help… Is this a  
problem with FastCGI? Is there another way to do it?

Thanks!

Posted at Nginx Forum:

> **[FastCGI PHP - unable to prematurely close connection to browser](https://forum.nginx.org/read.php?2,51310,51310#msg-51310)**
>
> Hi all! I am optimizing a few of the PHP scripts by: - doing all that generates output to browser - closing connection to browser - doing some more processing The processing bit cannot be avoided, but the speed of execution (from visitors' point of

---

<div class="post-metadata">

**Author:** ![cactus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/f475e1/32.png) [@cactus](https://www.ruby-forum.com/u/cactus)\
**Post date:** [February 6, 2010, 4:25pm UTC](https://www.ruby-forum.com/t/fastcgi-php-unable-to-prematurely-close-connection-to-browser/183027/2 "2010-02-06T16:25:59Z")

</div>

Hi,

I just tested your script and found that I needed to wait 10s to see the  
response. I am using Windows XP, Apache 2.1.11 worker MPM, PHP 5.3.1

It did not work asynchronously as you expected. Am I missing something  
here?

Regards

cactus wrote:

> Hi all!
> 
> I am optimizing a few of the PHP scripts by:
> 
> - doing all that generates output to browser
> - closing connection to browser
> - doing some more processing
> 
> The processing bit cannot be avoided, but the speed of execution (from  
> visitors’ point of view) is awesome this way. The problem is that we  
> have tried migrating the script to NginX + FastCGI (it works on Apache +  
> mod\_php) but it doesn’t close the connection anymore, it keeps it open  
> until the end… Which makes scripts slow again.
> 
> I am using Content-Length to allow server to figure out that all content  
> was already generated. This is the test case:
> 
> \<? header("Connection: close"); // not sure we need this one header("Content-Encoding: none"); ignore\_user\_abort(true); ob\_start(); echo ('Lets output something.'); // output Content-Length and flush buffers: $size = ob\_get\_length(); header("Content-Length: $size"); ob\_end\_flush(); flush(); // \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* // do some heavy processing here: sleep(5); function postproc() { flush(); sleep(5); } register\_shutdown\_function('postproc'); ?\>
> 
> The browser shows this page immediately in Apache+mod\_php but it waits  
> for 10 seconds in NginX + FastCGI.
> 
> I am a bit stuck here and would appreciate some help… Is this a  
> problem with FastCGI? Is there another way to do it?
> 
> Thanks!
> 
> Posted at Nginx Forum:  
> [http://forum.nginx.org/read.php?2,51310,51310#msg-51310](http://forum.nginx.org/read.php?2,51310,51310#msg-51310)

---

<div class="post-metadata">

**Author:** ![cactus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/f475e1/32.png) [@cactus](https://www.ruby-forum.com/u/cactus)\
**Post date:** [February 7, 2010, 3:51pm UTC](https://www.ruby-forum.com/t/fastcgi-php-unable-to-prematurely-close-connection-to-browser/183027/3 "2010-02-07T15:51:33Z")

</div>

First of all - thank you for your answer, I really appreciate it.

This is interesting - I have re-checked and it takes me 32ms to get the  
result on my development machine:  
Server Apache/2.2.9 (Debian) PHP/5.2.6-1+lenny4 with Suhosin-Patch  
X-Powered-By PHP/5.2.6-1+lenny4  
(PHP is installed as mod\_php)

Still, it is very important for me to be able to postpone processing. If  
I can’t do it on NginX I will probably have to find another server that  
can do this (overall load on the server is less important than quick  
response times in this case). I’m really hoping it’s just a config  
thing… 🙂

> From what I understand:

- PHP offers no way to prematurely close the connection except by  
setting and reaching Content-Length
- it is the web server (NginX / Apache) that can (should?) close the  
connection in this case

I can’t make PHP close the conenction, so my only hope is NginX. Can it  
be told to do so? Am I missing something?

Thanks again!

## Hoang Hoang Wrote:

> > The processing bit cannot be avoided, but the  
> > figure out that all content
> > 
> > function postproc() {
> 
> 51310
> 
> –  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).
> 
> * * *
> 
> nginx mailing list  
> [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> [mailman.nginx.org archive](http://nginx.org/mailman/listinfo/nginx)

Posted at Nginx Forum:  
[http://forum.nginx.org/read.php?2,51310,51672#msg-51672](http://forum.nginx.org/read.php?2,51310,51672#msg-51672)

---

<div class="post-metadata">

**Author:** ![cactus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/f475e1/32.png) [@cactus](https://www.ruby-forum.com/u/cactus)\
**Post date:** [February 7, 2010, 6:05pm UTC](https://www.ruby-forum.com/t/fastcgi-php-unable-to-prematurely-close-connection-to-browser/183027/4 "2010-02-07T18:05:33Z")

</div>

Hi,  
Not really to change you method on doing things. but you still will  
encounter slow response times for users eventually since that PHP  
process is _still_ processing things after that user is done and won’t  
be ready for the next user until it is done processing that script. So  
theoretical if you had 5 max PHP processes to handle client requests and  
say each PHP script take 500ms to complete but only 100ms is until your  
Connection: close. If 6 users hit your server at once. That user would  
have to wait the full 500ms until a free PHP process is available to  
process his request and then take the additional 100ms for it to see  
content. So now his experience for the page to load up is it takes  
almost 600ms.

Something i would suggest is using a messaging queue and a “few PHP  
process’s that are just designed to process the queue” this allows you  
to separate your user processing and your offline processing. Which will  
also allow you to offload your work to another server if it starts  
growing and such. here is website with some links to some message  
queues.

> **[Getting Started With Message Queues](https://blog.fedecarg.com/2008/11/03/getting-started-with-message-queues/)**
>
> When you’re building an infrastructure that is distributed all over the internet, you’ll come to a point where you can’t rely on synchronous remote calls that, for example, synchr…

v/r,  
Rob

---

<div class="post-metadata">

**Author:** ![cactus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/f475e1/32.png) [@cactus](https://www.ruby-forum.com/u/cactus)\
**Post date:** [February 7, 2010, 7:47pm UTC](https://www.ruby-forum.com/t/fastcgi-php-unable-to-prematurely-close-connection-to-browser/183027/5 "2010-02-07T19:47:23Z")

</div>

> So, still searching for the culprit that doesn’t close the connection to browser when Content-Length is reached… 🙂 Any ideas?
> 
> Or is this a FastCGI issue? Is there any other way to use PHP with NginX?

I believe this is a FastCGI issue. And nginx buffer’s the FastCGI  
response until FastCGI request is completed. The Header(“Connection:  
close”); is only used to prevent using Keep-alive connection. It tells  
the browser to terminate the connection and not keep them open, thus  
having no effect on when the data gets to the client.

A suggestion that might work as your needing is stripping your apache  
down to only using mod\_php and anything else you might want. and  
basically use it as a PHP process manager. Then you can just proxy your  
requests to apache for the php requests and turn proxy\_buffering off  
[GitHub - nginxinc/nginx-wiki: ARCHIVED -- Source for the now archived NGINX Wiki section of https://www.nginx.com · GitHub](http://wiki.nginx.org/NginxHttpProxyModule#proxy_buffering) which then  
_should_ produce the results you require. This allow you to use nginx  
for your static resources while just utilizing apache as just a PHP  
manager.

v/r,  
Rob

---

<div class="post-metadata">

**Author:** ![cactus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/f475e1/32.png) [@cactus](https://www.ruby-forum.com/u/cactus)\
**Post date:** [February 7, 2010, 7:31pm UTC](https://www.ruby-forum.com/t/fastcgi-php-unable-to-prematurely-close-connection-to-browser/183027/6 "2010-02-07T19:31:00Z")

</div>

Rob, thank you for the idea! We have used it before on other problems,  
though I had no idea there are libraries made to address this problem (I  
used my own solution). Thanks for the link, the projects there look very  
promising.

However, the way I see it, this approach is only useful if you want to  
distribute the load across other machines or across time (so that major  
work is done when the load is lower). In our case the application runs  
on several machines already and we can add more if necessary. Also, the  
work MUST be done at about the time the request was issued, so it cannot  
wait 10 minutes when the load might be lower. I think in that case the  
only solution is to compute when we get the requests, with the possible  
optimization of returning the output before all work is done. Or am I  
mistaken?

When the requests start getting slow (because they are waiting for other  
requests to finish) we can just add more machines (or enlarge max.  
number of PHP processes limit first 😉 and we’re done.

So, still searching for the culprit that doesn’t close the connection to  
browser when Content-Length is reached… 🙂 Any ideas?

Or is this a FastCGI issue? Is there any other way to use PHP with  
NginX?

Thanks again!

Posted at Nginx Forum:

> **[Re: FastCGI PHP - unable to prematurely close connection to browser](https://forum.nginx.org/read.php?2,51310,51782#msg-51782)**
>
> Hi all! I am optimizing a few of the PHP scripts by: - doing all that generates output to browser - closing connection to browser - doing some more processing The processing bit cannot be avoided, but the speed of execution (from visitors' point of

---

<div class="post-metadata">

**Author:** ![cactus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/f475e1/32.png) [@cactus](https://www.ruby-forum.com/u/cactus)\
**Post date:** [February 7, 2010, 8:48pm UTC](https://www.ruby-forum.com/t/fastcgi-php-unable-to-prematurely-close-connection-to-browser/183027/7 "2010-02-07T20:48:51Z")

</div>

I was hoping for a different answer - I guess I’ll just have to make a  
few of configurations and test what works best.

Thank you for helping out! 🙂

Posted at Nginx Forum:

> **[Re: FastCGI PHP - unable to prematurely close connection to browser](https://forum.nginx.org/read.php?2,51310,51813#msg-51813)**
>
> Hi all! I am optimizing a few of the PHP scripts by: - doing all that generates output to browser - closing connection to browser - doing some more processing The processing bit cannot be avoided, but the speed of execution (from visitors' point of

---

<div class="post-metadata">

**Author:** ![cactus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/f475e1/32.png) [@cactus](https://www.ruby-forum.com/u/cactus)\
**Post date:** [February 8, 2010, 10:25am UTC](https://www.ruby-forum.com/t/fastcgi-php-unable-to-prematurely-close-connection-to-browser/183027/8 "2010-02-08T10:25:22Z")

</div>

cactus wrote:

> is this a FastCGI issue?

You could try asking on a PHP mailing list, or looking through the PHP  
source code, to see if there is a function call that will close the  
FastCGI connection, while keeping the process open.

Tobia

---

<div class="post-metadata">

**Author:** ![cactus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/f475e1/32.png) [@cactus](https://www.ruby-forum.com/u/cactus)\
**Post date:** [February 14, 2010, 3:29pm UTC](https://www.ruby-forum.com/t/fastcgi-php-unable-to-prematurely-close-connection-to-browser/183027/9 "2010-02-14T15:29:16Z")

</div>

## Reinis R. Wrote:

> [http://php-fpm.org/wiki/Features#fastcgi\_finish\_re](http://php-fpm.org/wiki/Features#fastcgi_finish_re)  
> quest.28.29

Thanks for the info, this is good news! 🙂  
I hope it gets in production soon - will try it out anyway, just out of  
curiosity, I just need to find some extra time… 🙂

Thanks to all, enjoy!

Posted at Nginx Forum:  
[http://forum.nginx.org/read.php?2,51310,54461#msg-54461](http://forum.nginx.org/read.php?2,51310,54461#msg-54461)

---

<div class="post-metadata">

**Author:** ![cactus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/f475e1/32.png) [@cactus](https://www.ruby-forum.com/u/cactus)\
**Post date:** [February 8, 2010, 12:35pm UTC](https://www.ruby-forum.com/t/fastcgi-php-unable-to-prematurely-close-connection-to-browser/183027/10 "2010-02-08T12:35:18Z")

</div>

> > From what I understand:
> 
> - PHP offers no way to prematurely close the connection except by setting and reaching Content-Length

While I havent it used myself so not sure if it works 100% as expected  
there is such feature if you use php with the FPM  
patchset/manager - fastcgi\_finish\_request()

[http://php-fpm.org/wiki/Features#fastcgi\_finish\_request.28.29](http://php-fpm.org/wiki/Features#fastcgi_finish_request.28.29)

rr
