I often get questions about how to tune Tomcat for better performance. It is usually best to answer this only after first spending some time understanding the installation of Tomcat, the web site’s traffic level, and the web applications that it runs. But, there are some general performance tips that apply regardless of these important details. In general, Tomcat performs better when you:
- Start the JVM with a higher heap memory maximum using the -Xmx switch. The higher you make this, the more memory is available for Tomcat to use. This means that the JVM won’t need to invoke the garbage collector as often, which means that the server can focus a higher percent of its CPU time to serving web requests. That, in turn, means that requests can be completed faster. If your webapp runs on dedicated server hardware then just give the JVM as much of the machine’s physical memory as you can reasonably give it. If it is running on shared or virtual hardware, hook up JConsole or another console (such as MuleSoft’s Tcat Server console) to see how much memory your webapp tends to use under high load circumstances so that you can set a more reasonable maximum heap size setting.
- Start the JVM with its initial heap memory size (the -Xms switch) set the same value as its maximum memory size. This means the JVM never needs to resize and reallocate the heap memory while Tomcat is trying to serve requests.
- Tune the Connector (web server) thread pool settings to more closely match the web request load you have. This is difficult to do, but is very important to get right for best performance. The important Connector attribute for this is maxThreads. Setting this too low means that you may not have enough threads to handle all of the requests, in which case requests have to sit idle for some time without being handled until another request thread is freed up. Too low of a value also often means that Tomcat will be unable to take advantage of your server machine’s hardware. Setting maxThreads too high means that Tomcat startup time will take longer than necessary, and that during peak load times your server could slow down to a crawl trying to run that many request threads concurrently. You want to set it just right, based on your peak traffic pattern, and setting it just right is a matter of testing different values at that volume of traffic.
- Tune some additional Connector attribute settings:
- compression: Try turning this “on” and “off” and see which way performs best for your webapp. You may be surprised at the difference. By default it is “off“.
- compressableMimeTypes: If you enable compression, you should also set this attribute so that Tomcat knows what you want it to compress. Try setting it to something like “text/html,text/xml,text/javascript,text/css,text/plain“.
Other important factors in performance tuning include:
- Database performance: Many webapps use a relational database nowadays. The database connection pool settings are very important in that case. Mainly, the maxActive, maxIdle, and maxWait attributes of the Resource element where you define your database connection pool. Also, what about performance testing your database? Tomcat’s performance may be significantly slowed waiting on database queries to complete.
- HTTP caching headers: Enabling the user’s web browser to cache the static content of your webapps can greatly increase the user’s perceived performance. This is time consuming because tuning this optimally is almost always webapp specific and requires some studying of the webapp. But, making the caching work is all about setting the right set of response headers and their values when Tomcat serves the webapp’s static files.
- HTTPS is slower than HTTP, but this is a tradeoff. HTTPS is secure and HTTP is not. HTTPS is more chatty over the network during every request. Usually, when the user’s web browser is geographically distant from Tomcat, HTTPS makes requests take quite a bit longer. It may only be fixed by bringing Tomcat geographically closer to the users.
Also, the way people usually tend to lose about half of their Tomcat performance is to proxy all requests to Tomcat from Apache HTTPD. That configuration is not what you want if you need the best Tomcat performance. See my benchmark (with nice performance graphs) in the sample chapter Tomcat Performance Tuning of our book Tomcat: The Definitive Guide, Second Edition for the performance details of these configurations.