Tomcat vs Jetty vs Undertow — When to Switch
Fast recall
Quick revision
Core answer
tomcat.threads.busy saturation is the bottleneck and the workload is heavily I/O-bound. Switch to Jetty when you need many idle long-lived connections (WebSocket chat, SSE) or memory footprint at low traffic matters. Switch to Netty + WebFlux when the architecture is genuinely reactive and you can avoid blocking calls. Never benchmark the server in isolation — the application logic, downstream latencies, and JVM tuning dominate any server-level differences in real workloads.Whether the candidate can resist premature optimization and articulate measurable signals that justify a server change
Switching to Undertow or Netty based on a synthetic 'hello world' benchmark without measuring the actual production bottleneck
Walk through the diagnostic path: `/actuator/metrics` for thread saturation, GC logs for memory pressure, distributed traces for latency attribution; switching servers is the last step, not the first
Interview-ready guide
Interview answer
The honest answer is: don't switch without a measured reason. Tomcat is the default for a reason — it handles most workloads well, has the broadest tooling, and is what most teams already debug confidently.
The diagnostic path before any switch
- Confirm saturation, not application slowness — look at
tomcat.threads.busyvsthreads.config.max - Trace request latency end-to-end — slow downstream calls don't get faster with a different web server
- Tune Tomcat first — increase
threads.max, raiseaccept-count, adjustconnection-timeout - Move blocking work to
@Async— often eliminates the apparent need to switch
When the switch is genuinely justified
- Undertow when servlet throughput is the bottleneck and tuning didn't help
- Jetty when you have many idle long-lived connections (WebSocket, SSE) or need lower idle memory
- Netty + WebFlux when the architecture is genuinely reactive — and you can avoid blocking JDBC, blocking JMS, blocking HTTP clients
The mistakes to avoid
- Switching based on a synthetic benchmark — production behavior is dominated by application logic and downstream services
- Mixing blocking calls into a Netty reactive stack — worse than Tomcat, not better
- Forgetting that
server.tomcat.*properties silently no-op after a switch — re-audit configuration
In an interview, the strongest answer is: I'd default to Tomcat, instrument with Actuator and tracing, and only consider a server change after the diagnostic path points clearly to the I/O model as the bottleneck. The server is rarely the bottleneck.
Tomcat vs Jetty vs Undertow — When to Switch
Direct Answer
Don't switch without a measured reason. Tomcat is the default because it handles most workloads well and has the broadest tooling and documentation. Switch to Undertow when measured tomcat.threads.busy saturation is the bottleneck and the workload is heavily I/O-bound. Switch to Jetty when you need many idle long-lived connections (WebSocket chat, SSE) or memory footprint at low traffic matters. Switch to Netty + WebFlux when the architecture is genuinely reactive and you can avoid blocking calls. Never benchmark the server in isolation — the application logic, downstream latencies, and JVM tuning dominate any server-level differences in real workloads.
Common Mistakes & Pitfalls
Switching to Undertow or Netty based on a synthetic 'hello world' benchmark without measuring the actual production bottleneck
Check your understanding
Answer these without looking back at the article.
- What metrics would you watch to decide if Tomcat is the bottleneck?
- Why is mixing blocking JDBC inside WebFlux + Netty often worse than just using Tomcat?
- How would you A/B test a server switch without affecting production traffic?
- What server-specific properties become silently ignored after switching from Tomcat to Undertow?
Related interview prep categories
1Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.