Save Bandwidth by Configuring Compression in Apache

Overview

Save on data transfer costs from your host and improve the user experience for those with limited bandwidth, such as mobile devices. Learn how to use Apache’s deflate_module to compresses your files before being transmitted to browsers which support gzip. You could see savings of up-to 80%, depending on the type of content being served.

Content that is already heavily compressed, such as images, video, and audio will not benefit from additional compression; however, large text outputs like CSS, Javascript, HTML, and XML will see significant reducations.

Although new version of major browsers support compression, not every one does and older version of the major browsers may have the feature improperly implemented. The deflate module has options to make it flexible, allowing us to disable compression when a browser is either detected to not support it or has it poorly implemented.

 

Enabling the Compression Module

Apache uses the deflate_module to compress outgoing files using GZIP. The module is loaded by default in CentOS and Ubuntu installations. To verify, follow the following instructions.

CentOS

  1. Open Apache’s configuration file into a text editor.¬†nano /etc/httpd/conf/httpd.conf
  2. Ensure the module is being loaded by verifying the following line exists and is not commented out with a hashtag “#”.
    LoadModule deflate_module modules/mod_deflate.so

Ubuntu

  1. Enable the required module using the a2enmod command.
    sudo a2enmod deflate

Configure Compression

Compression is configured in either Apache’s server configuration or from within a virtual host. For more granular control, you can place it within a Directory or Location directive.

  1. Add the following line to enable compression.
    SetOutputFilter DEFLATE
  2. To disable compression for browsers that either do not support it or have it poorly implemented, match against their user agent strings and turn off deflate or disable compression for specific content types known to be problemantic.
    # Netscape 4.x has some problems...
    BrowserMatch ^Mozilla/4         gzip-only-text/html
    
    # Netscape 4.06-4.08 have some more problems
    BrowserMatch ^Mozilla/4.0[678] no-gzip
    
    # MSIE masquerades as Netscape, but it is fine
    BrowserMatch MSIE             !no-gzip !gzip-only-text/html
  3. We have the server set to compress everything going out. However, already heavily compressed files should not be, as it will waste valuable system resources doing so with no benefit. Let’s disable compression for our images, archives, and audio.
    # Don't compress images
    SetEnvIfNoCase Request_URI .(?:gif|jpe?g|png)$ no-gzip dont-vary
    
    # Don't compress file archives
    SetEnvIfNoCase Request_URI .(?:zip|tar|cab|gz|)$ no-gzip dont-vary
    
    # Don't compress audio
    SetEnvIfNoCase Request_URI .(?:mp3|wav|wma|ogg)$ no-gzip dont-vary

Fine Tuning Compression

You may find that default settings either do not compress as much as you’d like, or that the compression is eating to much system resources and needs to be dialed back. The deflate module allows for some fine tuning, giving you more control over how it is performed.

Compression Level

Lower or increase the level of compression used against your output by using and setting the DeflateCompressionLevel directive. The value most be between 1 (least amount of compression) and 9 (most amount of compression).

DeflateCompressionLevel 7

 

Memory Usage

The default settings use the maximum amount of memory required for compressing. However, if you are memory blocked, you may want to lower the amount of memory used during compression, so that other process aren’t starved. Use the DeflateMemLevel directive with a value between 1 (least amount of memory) and 9 (most amount of memory).

Lowering the memory usage will increase the amount of time needed to compress files. Keep an eye on request times if you choose to lower it from the default of 9.

DeflateMemLevel 6

 

Logging Compression Ratios

Enable logging of compression statistics to verify deflate is working and to see what ratios you are acheiving.

Log Ratios

To enable logging of ratios for requested files with web brower info, add the following to your web sites logging configuration.

DeflateFilterNote ratio

LogFormat '"%r" %b (%{ratio}n) "%{User-agent}i"' deflate
CustomLog logs/deflate_log deflate

Logging File Sizes and Transmission Sizes

You want even more information from your compression. We can enable deflate to log the file’s original size and it’s size after compression.

DeflateFilterNote Input instream
DeflateFilterNote Output outstream
DeflateFilterNote Ratio ratio

LogFormat '"%r" %{outstream}n/%{instream}n (%{ratio}n%%)' deflate
CustomLog logs/deflate_log deflate

 

Log File Output Example

The following is an example of what will be found in the output of your deflate log. The first value after the request URL is the compressed file size and the second is the original file size. The last is the compressed file’s size percentage against the original’s.

"GET /2014/09/my-article HTTP/1.1" 5392/18573 (29%)
"GET /css/base.css HTTP/1.1" 2987/14186 (21%)
"GET /imgs/logo.png HTTP/1.1" -/- (-%)
"GET /js/jquery-2.0.3.min.js HTTP/1.1" 29323/83616 (35%)
"GET /imgs/2014/09/my-article/figure01.png HTTP/1.1" -/- (-%)
"GET /imgs/2014/09/my-article/figure02.png HTTP/1.1" -/- (-%)

You can see some of the files in the log have no values specified, and instead display -/- (-%) at the end. This means they were not compressed, which is great as it shows our PNG images were not. That’s exactly the behavior we want.