trvrm.github.io
Streaming PHP Output with FPM and NGINX
Sun 25 October 2015
Problem: We had a PHP report that takes around 45 seconds to render. To give the user feedback that their report was actually being generated, I wanted to change our PHP installation to deliver at least some output to the client as soon as possible, rather than waiting until the entire page was rendered.
In general, PHP and NGINX work hard to buffer output, so this was mostly an exercise in fighting with PHP and NGINX to make them stop doing optimizations that do, in general, make sense. It turns out that to do this, we had to make changes at three levels of our software stack: in our PHP code, in our PHP configuration settings, and in our NGINX configuration.
I added this at the top of the file in question:
ob_implicit_flush(1);
This tells PHP to simulate calling flush()
after every output block.
I added a new .ini file in /etc/php5/fpm/conf.d
with the following setting:
output_buffering = Off
This tells PHP not to buffer output.
In the .conf file for the reporting site, I added
fastcgi_keep_conn on;
gzip off;
in the location block, and
ssl_buffer_size 1k;
in the server block. This last one took me a while to figure out - it defaults to 16k, and even with all the other changes made, when accessing the site via HTTPS, NGINX will still buffer your output.
This Stack Overflow question got me pointed in the right direction.