My site's admin section has a bunch of very slow report-generating scripts that echo
output line by line as it is generated. To have this output flushed immediately to the browser, instead of the user having to wait for minutes before they see any response, we have output_buffering
disabled and we call ob_implicit_flush
at the beginning of such scripts.
For convenience, I was considering just turning on the implicit_flush
setting in php.ini instead of adding ob_implicit_flush()
calls to every script that would benefit from it.
However, the documentation contains the following scary but unexplained remark:
implicit_flush
...
When using PHP within an web environment, turning this option on has serious performance implications and is generally recommended for debugging purposes only.
What are these "serious performance implications", and do they justify the manual's recommendation?
It may or may not be what the manual is hinting at, but one context in which either turning on implicit_flush
or calling ob_implicit_flush()
has serious performance implications is when using PHP with Apache through mod_php
with mod_deflate
enabled.
In this context, flush()
calls are able to push output all the way through mod_deflate
to the browser. If you have any scripts that echo large amounts of data in small chunks, flushing every chunk will cripple mod_deflate
's ability to compress your output, quite possibly resulting in a 'compressed' form that is larger than the original content.
As an extreme example, consider this simple script which echoes out a million random numbers:
<?php
header('Content-Type: text/plain');
for ($i=0; $i < 1000000; $i++) {
echo rand();
echo "\n";
}
?>
With output_buffering
off and implicit_flush
also off (for now), let's hit this in Chrome with the dev tools open:
Note the Size/Content column; the decompressed output is 10.0MB in size, but thanks to mod_deflate
's gzip compression, the entire response was compressed down to 4.8MB, roughly halving it in size.
Now hitting exactly the same script with implicit_flush
set to On
:
Once again, the 'decompressed' output is 10.0MB in size. This time, though, the size of the HTTP response was 28.6MB - mod_deflate
's 'compression' has actually trebled the size of the response.
This, for me, is more than enough reason to heed the PHP manual's advice of leaving the implicit_flush
config option off, and only using ob_implicit_flush()
(or manual flush()
calls) in contexts where doing so actually serves a purpose.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With