Tuesday, May 4, 2010

Tomcat Performance: gzip Compression

One of the ways of increasing server performance, is by reducing the amount of data passed on the network. This can be done by using compression.
Most modern web browsers support compression. If a browser supports compression it will send in the request header the following string:
Accept-Encoding: gzip,deflate
The server can identify this header and return a compressed response. If the browser doesn’t send this header, the server will always return an uncompressed response. If the response is compressed, it will return in the response header the following string:
Content-Encoding: gzip
Now the client knows that the response is gzip compressed.
Tomcat supports gzip compression out of the box. You can easily add compression support to your server, without writing a single line of code.
To turn on Tomcat compression, you should edit server.xml, which is located under Tomcat conf directory. The compression is added to the connector element:
<Connector port="8080" protocol="HTTP/1.1" 
connectionTimeout="20000" redirectPort="8443" 
compression="on" compressableMimeType="text/html,
text/xml,text/plain,text/javascript,text/css" 
/>
Note that you can determine the mime types for which tomcat should do the compression.
Sometimes there are user agents (web browsers) that has problems with gzip compression, even If they send Content-Encoding: gzip direction in the request header. In order to exclude specific user agents from being served with gzip compression you can use the property: noCompressionUserAgents. You can use regular expression to define user agents list separated with commas:
<Connector port="8080" protocol="HTTP/1.1" 
connectionTimeout="20000" redirectPort="8443" 
compression="on" compressableMimeType="text/html,text/xml,text/plain,text/javascript,text/css" 
noCompressionUserAgents=".*MSIE 6.*"
/>


If a file is too small, the overhead of compressing it may take longer than sending it uncompressed. You can define a minimum size for which a compression should not be done:
<Connector port="8080" protocol="HTTP/1.1" 
connectionTimeout="20000" redirectPort="8443"
compression="on" compressableMimeType="text/html,text/xml,text/plain,text/javascript,text/css" 
noCompressionUserAgents=".*MSIE 6.*"
compressionMinSize="1024"
/>

8 comments:

  1. Good think to have gzip compression in Tomcat.
    There are also several other ways to improve tomcat's performance. I wrote about them here: http://touk.pl/blog/2010/08/23/glimpse-on-tomcat-performance-tuning/ just look if You are interested.

    Greetings

    ReplyDelete
  2. This post is specifically for Tomcat compression.
    I read you post. It is a nice addition. Thanks.

    ReplyDelete
  3. the book Pro Apache Tomcat 6 says that the value of the compression can be yes, no, or the minimum size, and they do not list a compressionMinSize attribute to the Connector. Is this new for Tomcat 6?

    ReplyDelete
  4. Sorry, I have no idea how it used to be on versions before Tomcat6. On Tomcat6 this parameter should be the one.

    ReplyDelete
  5. Hi Guy,

    thanks for the post. Unfortunately I think there is an error. I just copy-pasted your code and got angry because it was working for html but not for css and javascript. I found out there seems to be a spelling mistake in your connector definition: the attribute is called compressableMimeType not compressableMimeTypes. There is no "s" on the end. Maybe you want to correct this.

    Cheers

    Marc

    ReplyDelete
  6. Hi Guy,

    thanks for the blog post, but I think there is a spelling mistake. The attribute for the connector is called "compressableMimeType" not "compressableMimeTypes" (no "s" at the end). I copy-pasted your connector definition, and it just gzipped the html, but not css and javascript. This is the default. With the correct attribute it gzips everything properly.

    Cheers

    Marc

    ReplyDelete
  7. Hi Marc, thanks for the correction. I will fix the blog post.

    ReplyDelete
  8. Hi, i tried this for PDF files in windows platform. It didn't work. Is this for only text response?

    Thanks.

    ReplyDelete