How To Save Traffic With nginx's HttpGzipModule (Debian Squeeze)
Version 1.0
Author: Falko Timme
Follow me on Twitter
In this tutorial I will describe how to configure HttpGzipModule on an nginx web server (on Debian Squeeze). HttpGzipModule allows nginx to compress files and deliver them to clients (e.g. browsers) that can handle compressed content which most modern browsers do. With HttpGzipModule, you can compress HTML, CSS, Javascript, text or XML files to approx. 20 - 30% of their original sizes, thus saving you server traffic and making your modem users happier.
Compressing files causes a slightly higher load on the server, but in my experience this is compensated by the fact that the clients' connection times to your server decrease a lot. For example, a modem user that needed seven seconds to download an uncompressed HTML file might now only need two seconds for the same, but compressed file.
By using HttpGzipModule you don't have to be afraid that you exclude users with older browsers that cannot handle compressed content. The browser negotiates with the server before any file is transferred, and if the browser does not have the capability to handle compressed content, the server delivers the files uncompressed.
I do not issue any guarantee that this will work for you!
1 Preliminary Note
I'm assuming you have a working nginx setup on your Debian Squeeze server, e.g. as shown in this tutorial: Installing Nginx With PHP5 And MySQL Support On Debian Squeeze
2 Configuring HttpGzipModule
Open /etc/nginx/nginx.conf:
vi /etc/nginx/nginx.conf
You will find that gzip compression is already enabled (in the http {} section):
[...] http { include /etc/nginx/mime.types; access_log /var/log/nginx/access.log; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 2; tcp_nodelay on; gzip on; gzip_disable "MSIE [1-6]\.(?!.*SV1)"; include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; } [...] |
gzip on; enables gzip compression.
gzip_disable "MSIE [1-6]\.(?!.*SV1)"; disables gzip compression for browsers that don't support it (in this case MS Internet Explorer before version 6 SV1).
Of course, we can fine-tune this configuration (you can find a list of possible configuration directives on http://wiki.nginx.org/HttpGzipModule):
gzip_http_version 1.1; - This enables gzip compression for HTTP request version 1.1. As the Content-Length header is not set, this will make Keepalives impossible with version 1.0.
gzip_vary on; - This sets the response header Vary: Accept-Encoding. Some proxies have a bug in that they serve compressed content to browsers that don't support it. By setting the Vary: Accept-Encoding header, you instruct proxies to store both a compressed and uncompressed version of the content.
gzip_comp_level 6; - This is the compression level (between 1 and 9) where 1 is the least compression (fastest) and 9 is the most (slowest).
gzip_proxied any; - This configures how requests coming from a proxy should be handled. any means enable compression for all requests.
gzip_types text/plain text/html text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript text/x-js; - This tells nginx what file types to compress (text/html is always compressed). As Javascript files might have different file types on each server, I have included several possible Javascript MIME types (the same goes for XML).
gzip_buffers 16 8k; - This assigns the number and the size of the compression buffers. The default is gzip_buffers 4 4k; or gzip_buffers 4 8k;, but I have increased that value to make sure that big Javascript or CSS files can be compressed as well (see http://blog.leetsoft.com/2007/7/25/nginx-gzip-ssl for more details).
So my final configuration looks as follows:
[...] http { include /etc/nginx/mime.types; access_log /var/log/nginx/access.log; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 2; tcp_nodelay on; gzip on; gzip_http_version 1.1; gzip_vary on; gzip_comp_level 6; gzip_proxied any; gzip_types text/plain text/html text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript text/x-js; gzip_buffers 16 8k; gzip_disable "MSIE [1-6]\.(?!.*SV1)"; include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; } [...] |
Reload nginx:
/etc/init.d/nginx reload
3 Testing
To test if your configuration works, you can install the Live HTTP Headers plugin for Firefox and access text file through Firefox (e.g. a static HTML page). In the Live HTTP Headers output, you should now see that the client (Firefox) sent an Accept-Encoding: gzip,deflate header to tell the server that it accepts compressed content in the formats gzip and deflate; the server should compress the file and send it with a Content-Encoding: gzip header (as you see in this example, nginx also sets the Vary: Accept-Encoding header):
4 Links
- nginx HttpGzipModule: http://wiki.nginx.org/HttpGzipModule
- Live HTTP Headers Plugin for Firefox: https://addons.mozilla.org/en-us/firefox/addon/live-http-headers/
- Debian: http://www.debian.org/
About The Author
Falko Timme is the owner of Timme Hosting (ultra-fast nginx web hosting). He is the lead maintainer of HowtoForge (since 2005) and one of the core developers of ISPConfig (since 2000). He has also contributed to the O'Reilly book "Linux System Administration".