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

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

Ensuring Missing Resources Are Created Automatically in a Spring Boot Project

Singular Update Queue: A Smarter Way to Handle Updates