Apache Tomcat with default settings can handle dozens of concurrent users. For hundreds and thousands you need tuning. Here is our experience with Tomcat 7 under high load.
Connector — NIO vs. BIO¶
The default BIO connector (blocking I/O) allocates one thread per connection. With 200 concurrent connections = 200 threads. The NIO connector (non-blocking I/O) handles thousands of connections with dozens of threads. For production servers always use NIO: protocol=org.apache.coyote.http11.Http11NioProtocol.
Thread pool¶
maxThreads: maximum number of threads for processing requests. For NIO: 150–300 depending on load. acceptCount: queue of requests waiting for a thread — when full, the server returns 503. minSpareThreads: minimum number of pre-warmed threads.
Keep-Alive¶
HTTP keep-alive keeps the connection open for multiple requests. Reduces TCP handshake overhead. maxKeepAliveRequests=100, keepAliveTimeout=15000 ms. In a load-balanced environment, aggressive keepalive can be counterproductive.
Compression¶
compression=on, compressionMinSize=2048, compressibleMimeType for text/html, text/css, application/javascript. Saves bandwidth at the cost of CPU. For static files it’s better to pre-compress on disk.
Access log¶
Enable access log with the response time pattern (%D). Analyzing the access log reveals slow requests that JMX metrics don’t capture.
Summary¶
NIO connector, properly configured thread pool, keep-alive and compression. Measure before and after any change — tuning without benchmarks is just guessing.
Need help with implementation?
Our experts can help with design, implementation, and operations. From architecture to production.
Contact us