Use Apache mod_deflate To Compress Web Content (Accept-Encoding: gzip)


Sat Apr 04 21:45:00 2009 -0700

After setting up my mobile blog at, I started looking for ways to improve the content delivery speed of this service to mobile devices. On the server-side, I’m fairly sure I implemented just about every hack imaginable to squeeze every bit of performance I could from the PHP engine. At this point, my only bottleneck was the actual content delivery chain. I can’t control how fast my data is transferred over a wireless (2G/3G?) network because of factors outside of my control, but I can help grease the skid. To do so, I activated Apache’s mod_deflate extension which compresses the content of an HTTP response before its delivered to the client.

The mod_deflate module uses gzip to deflate the HTTP response body. Obviously, since the response is compressed, that means there’s less data to transfer. Hence, it takes less “cycles” (packets, octets, whatever) to get the data to the client. In short, using compression within the confines of HTTP can often dramatically improve the “speed” of your site or mobile portal on a wireless network. Of course, not only wireless clients benefit from the performance improvement, but typically wireless devices see more of an improvement than an average broadband user.

First, I verified that mod_deflate is installed and pre-activated with Apache on my CentOS 5 box:

#/~> cat /etc/httpd/conf/httpd.conf | grep mod_deflate
LoadModule deflate_module modules/

Second, I hacked my VirtualHost configuration a bit to activate the mod_deflate output filter. Using the instructions on the mod_deflate homepage, I configured my VirtualHost to use the highest compression level possible on every response except for binary image data. I also defined a custom “deflate” log so I can check the compression ratio on any responses:

<VirtualHost *:80>

  DocumentRoot /my/server/root/

  DeflateCompressionLevel 9
  SetOutputFilter DEFLATE
  BrowserMatch ^Mozilla/4 gzip-only-text/html
  BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
  SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|ico)$ no-gzip dont-vary
  Header append Vary User-Agent env=!dont-vary

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

  ErrorLog logs/
  CustomLog logs/ combined


This works quite nicely. Looking at the custom deflate log, my content compression ratio is about 40-50% on average. Not bad for less than 5 minutes of work!

Some things to consider when using mod_deflate:

  • It wasn’t immediately clear to me if mod_deflate looked for the Accept-Encoding HTTP request header to verify that the client supports gzip compression. At least, there was no mention of this on the mod_deflate homepage — but as it turns out, yes, mod_deflate does look through the HTTP request headers for Accept-Encoding: gzip and will not compress the response if the client does not support it.
  • Of course, not all clients support compression.
  • Compression will use additional CPU cycles on the client and the server. If a large majority of your target audience is using slow mobile devices, then you might want to think twice about HTTP compression. Generally speaking though, todays mobile clients should have plenty of CPU power to handle simple gzip compression.
  • High-traffic sites will want to think twice about compression. You wouldn’t want the added CPU consumption from compression to impact your overall site experience.


apache performance