Increase speed and reduce bandwidth usage

Apache’s mod_deflate module provides the DEFLATE output filter that allows output from your server to be compressed before being sent to the client over the network.

There are two ways of enabling gzip compression:

  1. Using Apache’s mod_deflate
  2. Using output buffering

Encoding the output and setting the appropriate headers manually makes the code more portable. Keep in mind that there are hundreds of Linux distributions, each slightly different to significantly different. To allow portability the application should not make assumptions about the OS or config involved.

Using Apache

1. Enable mod_deflate

Debian/Ubuntu:

$ a2enmod deflate
$ /etc/init.d/apache2 force-reload

2. Configure mode_deflate

$ nano /etc/apache2/mods-enabled/deflate.conf

#
# mod_deflate configuration
#
<IfModule mod_deflate.c>
 AddOutputFilterByType DEFLATE text/plain
 AddOutputFilterByType DEFLATE text/html
 AddOutputFilterByType DEFLATE text/xml
 AddOutputFilterByType DEFLATE text/css
 AddOutputFilterByType DEFLATE application/xml
 AddOutputFilterByType DEFLATE application/xhtml+xml
 AddOutputFilterByType DEFLATE application/rss+xml
 AddOutputFilterByType DEFLATE application/javascript
 AddOutputFilterByType DEFLATE application/x-javascript

 DeflateCompressionLevel 9

 BrowserMatch ^Mozilla/4 gzip-only-text/html
 BrowserMatch ^Mozilla/4\.0[678] no-gzip
 BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

 DeflateFilterNote Input instream
 DeflateFilterNote Output outstream
 DeflateFilterNote Ratio ratio
</IfModule>

Using output buffering

Create a gzip compressed string in your bootstrap file:

try {
    $frontController = Zend_Controller_Front::getInstance();
    if (@strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false) {
        ob_start();
        $frontController->dispatch();
        $output = gzencode(ob_get_contents(), 9);
        ob_end_clean();
        header('Content-Encoding: gzip');
        echo $output;
    } else {
        $frontController->dispatch();
    }
} catch (Exeption $e) {
    if (Zend_Registry::isRegistered('Zend_Log')) {
        Zend_Registry::get('Zend_Log')->err($e->getMessage());
    }
    $message = $e->getMessage() . "\n\n" . $e->getTraceAsString();
    /* trigger event */
}

Reference

Use mod_deflate to compress Web content delivered by Apache

About these ads

18 thoughts on “Increase speed and reduce bandwidth usage

  1. Doesn’t the mod_deflate output filter automatically set the Content-Encoding header for matching MIME types? So in that case is it necessary to set the same header in PHP?

  2. Yes, but if you are building portable applications, then you have to set the header in the application.

  3. Maybe I’m missing something? To check my memory I tried a plain HTML file on a server with mod_deflate enabled. Response headers:

    Date: Tue, 07 Jul 2009 02:09:45 GMT
    Server: Apache/2.0.52 (Red Hat)
    Last-Modified: Tue, 07 Jul 2009 02:09:03 GMT
    Etag: “c68003-163-1b48cdc0″
    Accept-Ranges: bytes
    Vary: Accept-Encoding
    Content-Encoding: gzip
    Content-Length: 259
    Content-Type: text/html

    200 OK

  4. Firstly, Ubuntu (9.04) is already configured to use mod_deflate and php output is gziped automatically.

    Secondly, mod_deflate is output filter thus for no Ubuntu system is enough to do:
    AddOutputFilterByType DEFLATE text/html
    (or AddOutputFilterByType DEFLATE application/x-httpd-php with FAST CGI)
    and turn on mod_defalte (or follow the step 2)

    You don’t have to encode output as you described in the step 3 but you only have to set proper Content-type header (text/html) to get gzip worked.

  5. @Gerard:
    There is only increased memory consumption and little bit (between 1-9) of CPU time:
    Compression: 400k + ( 8 x block size )

    Block size is 900k for 9 and 100k for 1. Compression ratio is growing up with block size. As was mentioned 3 or 4 is a good start but I recommend to use 9 always.

    I your server serve 1k request *simultaneously* you need at least (400k + (8 * 900k)) * 1k ~ 8GB ram…

  6. @Ondrej

    I’m using Fedora 8 and Ubuntu 8.04. I didn’t know 9.04 enabled the module by default (it makes sense), thanks for the tip. However, I do recommend having some guidelines for increasing portability during each of the key activities of development and maintenance, such as setting headers and compressing output.

  7. It’s not special to Ubuntu 9.04. I would rather expect it to be related to Apache version – I’ve set up mod_deflate for an Apache 2, Debian 4 install, gzip compression was handled automatically with no php intervention.

  8. @Federico
    I forgot emphasize main idea that you don’t have to do anything which is mentioned in the step 3 when you set the correct Content-type header (and you have proper setup).

  9. @Ondrej Are you saying that if you enable and configure the deflate module in Apache the output is automatically encoded and the headers automatically added regardless of the web server and operating system you are using?

  10. @Federico
    As Fake51 mentioned Apache 2.0 (and higher) should this do automatically when you turn on mod_deflate and the output from the php script has correct Content-type header.

  11. As usual I forgot something:
    Content negotiation (step 3 in your sample) is provided by mod_negotiation which is compiled by default in to Apache 2.0 or higher.

  12. This has been my experience as well. Including:

    AddOutputFilterByType DEFLATE text/html

    in the vhost is enough to compress any text/html content (including PHP output), and set all the appropriate headers.

    I’ve been using it for a while on both Ubuntu and CentOS servers and have never done anything like you have in step 3.

  13. Yes, you are right. I’m going to edit the post and some of my comments.

    So basically there are 2 methods for compressing the content:

    1. Using Apache: Enable and configure mod_deflate and the server will automatically encoded the content and set the appropriate headers.
    2. Using PHP: Encode the content and manually set the headers in the application.

    Barry, Ondrej, Fake51 and Tim: Thanks for the corrections and extra info!

  14. Pingback: Cristian Neagu

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s