Tomcat vs Jetty vs GlassFish vs Quarkus — A Deep, Story-Driven Guide (with Eureka)
A blog that makes the choice crystal clear for both freshers and senior engineers
The story: SkyHospital’s Java journey (and why “server choice” is never random)
Meet SkyHospital — a product company building hospital software:
Admin portal for hospital staff
Doctor dashboard
Patient appointment booking
Billing & reports
Notifications (email/SMS/WhatsApp)
Eventually: multiple microservices
They start small, then grow, and at each stage their “best server choice” changes.
This is exactly how it happens in real life.
Chapter 1 — The first release (Tomcat enters)
SkyHospital’s first app is a single codebase:
JSP pages for Admin UI
Spring MVC controllers
A couple of servlets and filters
Simple SQLite database (for MVP)
Packaged as a WAR file
Deployment reality:
The company has:
1 VM
1 admin who restarts services
A release once a week
Minimal monitoring
The CTO says:
“I want something stable that every Java engineer understands.”
✅ Why they choose Tomcat
Tomcat is a servlet container. That means:
It runs servlet-based web apps
It’s lightweight compared to full enterprise servers
It’s extremely common in production
Tomcat advantage in this stage
Predictability beats sophistication.
Tomcat is:
easy to configure
easy to debug
easy to hire for
Drawbacks (that don’t matter yet)
Not “super optimized” for cloud-native scaling
Doesn’t provide enterprise platform services (transactions/messaging/etc.) out of the box
Real-life example outcome
SkyHospital ships fast:
Deploy WAR → works
Simple rollback → redeploy previous WAR
Logs are familiar
Team is productive
Tomcat wins because it’s the safest and simplest choice.
Chapter 2 — The kiosk product (Jetty enters)
A new business deal arrives:
“Hospitals want a self-service kiosk app in the lobby.”
Constraints change dramatically:
runs on limited hardware
must start quickly after reboot
must run offline sometimes
IT team refuses to “install and manage a server separately”
app must be shipped as a single executable (a JAR)
Now the team needs:
“a web server inside the app.”
✅ Why they choose Jetty
Jetty is also a servlet container, but it shines as embedded.
Jetty is often chosen when:
you want
java -jar kiosk.jarthe server is packaged inside your app
you want minimal external dependencies
What makes Jetty perfect here
Smaller footprint
Embedded-first design
Great for controlled environments
Drawbacks
In many enterprises, operations teams are more “Tomcat-friendly”
Smaller mindshare than Tomcat (still widely used)
Real-life example outcome
The kiosk team ships a single file:
java -jar kiosk.jarno separate Tomcat install
consistent behavior across machines
Jetty wins because it matches the deployment model perfectly.
Chapter 3 — The enterprise hospital chain (GlassFish enters)
SkyHospital lands a large customer:
A chain of hospitals says:
“We need strict transactions, auditing, and messaging. Also, we want Jakarta EE standards.”
New requirements arrive:
billing must be transaction-safe (no partial updates)
asynchronous messaging for audit logs
standardized security policies
team prefers Jakarta EE patterns
multi-module application packaging (EAR style)
Now the team faces a choice:
implement transactions, messaging, etc. themselves, or
use a platform that provides these features
✅ Why they choose GlassFish (or Payara/WildFly in many orgs)
GlassFish is a full Jakarta EE application server.
It provides built-in:
JTA transactions
JMS messaging
CDI dependency injection
security integration
JPA integration patterns
administrative tooling
What makes GlassFish great here
Instead of writing infrastructure code, the team uses platform services:
“transaction boundaries” are managed by container
messaging is standardized
deployment packaging supports large enterprise systems
Drawbacks (real and important)
heavier runtime (memory + startup)
more operational complexity
slower deployments
if you don’t need enterprise features, it’s “too much”
Real-life example outcome
The enterprise customer is happy because:
transactional consistency is reliable
platform meets compliance expectations
operations team gets admin tooling
GlassFish wins when your system is enterprise-heavy and standards-driven.
Chapter 4 — Microservices + scaling problems (Quarkus enters)
SkyHospital grows rapidly. Now they have:
appointment-service
billing-service
lab-service
notifications-service
auth-service
reporting-service
They deploy to Kubernetes.
Suddenly, there’s a new problem:
“We can’t scale cost-effectively. Services start slowly and use too much memory.”
This is classic when you run many JVM services:
each service needs memory
cold start time affects autoscaling
infra cost rises
✅ Why they choose Quarkus
Quarkus is not a traditional server like Tomcat. It’s a cloud-native runtime:
very fast startup
low memory usage
optimized for containers and Kubernetes
supports building native images for extreme cold-start speed
What makes Quarkus perfect here
When you run 20 services:
memory savings add up dramatically
fast startup improves scaling and resilience
developer experience supports rapid iteration
Drawbacks
not a “drop WAR and run” model
requires adopting Quarkus extensions
migration from old servlet/JSP apps can require refactoring
Real-life example outcome
After migration:
pods scale faster
cloud costs drop
release cycles speed up
fewer “slow start” incidents
Quarkus wins when you’re cloud-native and scaling matters.
Where Eureka fits (and why it changes architecture decisions)
SkyHospital’s microservices need service discovery:
“How does billing-service find appointment-service?”
There are two eras:
Era A: VM-based microservices (Eureka makes sense)
In a VM world, IPs change and you need a registry.
Eureka provides:
service registration
discovery
client-side load balancing
Eureka + Tomcat/Jetty (most common)
If your services are Spring Boot and running on VMs:
Eureka is easy
mature patterns exist
good developer velocity
Why it’s chosen:
Because the platform lacks built-in discovery.
Era B: Kubernetes microservices (Eureka becomes less necessary)
In Kubernetes, service discovery is built-in:
Services get stable DNS names
Load balancing is handled by Kubernetes
So modern teams prefer:
✅ Kubernetes DNS + Services
instead of Eureka.
Eureka + Quarkus?
Possible, but often avoided because:
Kubernetes already solves the same problem more simply
fewer moving parts is better
The “No Confusion” Decision Guide
Choose based on your deployment reality
✅ Tomcat — when you have WAR apps and classic web
Best for:
JSP/Servlet/Spring MVC WAR deployments
traditional enterprise hosting
stable ops model
Avoid when:
you need cloud-native scaling efficiency
✅ Jetty — when you want embedded, lightweight, packaged runtime
Best for:
java -jardeploymentstools, kiosks, embedded products
lightweight services
Avoid when:
ops team demands a standard container deployment model
✅ GlassFish — when you truly need Jakarta EE platform features
Best for:
JTA transactions, JMS, container-managed services
enterprise packaging (EAR)
standards-driven orgs
Avoid when:
you don’t need these features (it becomes heavy overhead)
✅ Quarkus — when you’re building cloud-native microservices
Best for:
Docker/Kubernetes workloads
fast autoscaling
low memory usage
modern microservices
Avoid when:
your app is WAR/JSP heavy (migration cost can be high)
Pros & Cons Table (final clarity)
| Tech | What it is | Biggest Strength | Biggest Drawback | Best Use Case |
|---|---|---|---|---|
| Tomcat | Servlet container | Stable, common, WAR-friendly | Not cloud-optimized by default | Classic web apps/WAR |
| Jetty | Servlet container | Lightweight, embedded-friendly | Less “default enterprise standard” | Embedded server apps |
| GlassFish | Jakarta EE server | Enterprise platform services built-in | Heavy + ops complexity | EE enterprise apps |
| Quarkus | Cloud-native runtime | Fast startup + low memory | Not WAR deployment model | Microservices/k8s |
The story-based takeaway (simple and true)
Think of them as vehicles:
Tomcat = reliable family car (WAR apps, stable ops)
Jetty = lightweight scooter (embedded and portable)
GlassFish = full bus with facilities (enterprise platform services)
Quarkus = race car built for modern highways (cloud-native scaling)
Final conclusion
If you’re choosing today in most modern companies:
Legacy WAR → Tomcat
Embedded server-in-app → Jetty
Heavy Jakarta EE platform requirements → GlassFish/Payara
Microservices on Kubernetes → Quarkus (or Spring Boot)
And for discovery:
VMs → Eureka can make sense
Kubernetes → prefer K8s service discovery over Eureka
If you want, I can tailor the same “SkyHospital story” to your environment:
Spring Boot + Eureka on VMs?
Quarkus on Kubernetes?
Migrating from Tomcat WAR to microservices?
Tell me your stack and deployment style and I’ll recommend the best path.
Comments
Post a Comment