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.jar

  • the 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.jar

  • no 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 -jar deployments

  • tools, 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)

TechWhat it isBiggest StrengthBiggest DrawbackBest Use Case
TomcatServlet containerStable, common, WAR-friendlyNot cloud-optimized by defaultClassic web apps/WAR
JettyServlet containerLightweight, embedded-friendlyLess “default enterprise standard”Embedded server apps
GlassFishJakarta EE serverEnterprise platform services built-inHeavy + ops complexityEE enterprise apps
QuarkusCloud-native runtimeFast startup + low memoryNot WAR deployment modelMicroservices/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

Popular posts from this blog

Concurrency Control from First Principles

CAP Theorem, Explained: Why Distributed Systems Can’t Have It All