Why Quarkus Is Winning Cloud-Native Java: Build-Time Over Runtime Reflection
The article explains why Quarkus is gaining adoption over Spring Boot for cloud-native Java, detailing its build-time processing architecture that eliminates runtime reflection, resulting in 1.3s JVM startup, 200ms native startup, 2.5x lower memory, and 2.7x higher throughput, with trade-offs like ecosystem maturity and Native Image complexity.
Introduction
A reader asked for an open-source framework recommendation for a Java stack "slimming" evaluation. Their company runs over 200 Spring Boot services, each averaging 512 MB heap. On Kubernetes, the idle JVM heap waste alone costs hundreds of thousands of dollars per year. Rolling releases require a 30-minute window just for pod startup. The reader noted: "Spring Boot isn't bad; it's just a poor fit for cloud-native environments."
Some may ask: "Spring Boot has worked fine for years, why switch?"
1. Java Framework Dilemmas in Cloud-Native Environments
Spring Boot inherits a runtime reflection model that fundamentally mismatches Kubernetes' elastic scaling model . Traditional Java applications face three dilemmas:
1.1 Startup Time Dilemma
Spring Boot applications take 5–15 seconds for context initialization. Class loading, bean instantiation, dependency injection, and auto-configuration scanning run serially on the main thread before JIT compilation kicks in, amplifying startup latency.
1.2 Memory Footprint Dilemma
A minimal Spring Boot web app often exceeds 200 MB resident memory, while an equivalent Go app may need only 20 MB. In Kubernetes, memory scales linearly with replica count; an extra 200 MB per replica at 100 replicas translates to thousands of dollars per month.
1.3 Warm-up Dilemma
Even after startup, the JIT compiler requires thousands of method invocations to identify hotspots. During the first few minutes, throughput may be only 30–50% of steady state. For on-demand scaling, new replicas receiving traffic immediately can cause request timeouts.
The root cause is not Java itself, but the runtime reflection model used by Spring, Hibernate, Jackson, and nearly all mainstream frameworks. This model offers development-time flexibility but imposes heavy runtime costs.
2. Quarkus Build-Time Processing Architecture
Quarkus' core contribution is a fully build-time framework kernel that satisfies Native Image's closed-world assumption, making Native Image viable for production Java applications. In plain terms: Spring Boot defers work to runtime; Quarkus completes it at build time.
3. Underlying Principles
3.1 Build-Time Processing Full Flow
Contrast with Spring Boot's runtime flow: Spring Boot executes "scan → parse → build bean definitions → reflectively create → inject" at startup. Quarkus moves the first four steps to the build phase; runtime only loads pre-generated code. This is the fundamental reason startup drops from 5.6 s to 1.3 s.
3.2 ArC Dependency Injection: Build-Time Code Generation vs Runtime Reflection
Key insight: ArC knows at build time that GreetingService depends on GreetingBean and directly generates bytecode equivalent to new GreetingService(new GreetingBean()). No reflective constructor lookup, no reflective field injection, no dynamic proxy generation. Dependency injection shifts from a "runtime operation" to "compile-time generated code."
3.3 Virtual Thread Scheduling Model
Using virtual threads in Quarkus:
@RunOnVirtualThread
@GET
@Path("/blocking-operation")
public String blockingOperation() {
// This code runs on a virtual thread
// Can use simple blocking APIs
// While achieving near-reactive concurrency
return repository.findSomething();
}Core value: Traditional platform threads consume ~1 MB stack each and idle while blocked. Virtual threads use M:N scheduling — many virtual threads multiplex onto few carrier threads; when a virtual thread blocks, it yields the carrier thread to run another virtual thread. You keep writing simple blocking code while gaining concurrency close to reactive programming.
4. Performance Data
4.1 Official Benchmark (March 2026)
Throughput: Quarkus 19,255 tps vs Spring Boot 7,238 tps — 2.7x higher
JVM Startup: Quarkus 2.9 s vs Spring Boot 6.6 s — 2.3x faster
Memory Usage: Quarkus 269 MB vs Spring Boot 583 MB — 2.2x lower
4.2 BMW Romania Independent Test (August 2026)
BMW Romania CTO Alex Diniș conducted a rigorous side-by-side test: identical service with REST endpoints, business logic, and an embedded ML sentiment classification model implemented in both frameworks.
JVM Startup: Quarkus 1.3 s vs Spring Boot 5.6 s — 4.3x faster
Native Startup: Quarkus ~200 ms vs Spring Boot ~2 s — 10x faster
Idle Memory: Quarkus 88 MB vs Spring Boot 204 MB — 2.5x lower
Docker Image: Quarkus smaller
Real-world impact: Assuming 200 scale-out events per day, 2 pods each, the 4.3-second startup gap multiplied by 400 pod starts yields ~30 minutes of daily unserviceable time . At 50 requests/second, that equals ~100,000 delayed or failed requests per day .
5. Code Practice
5.1 Project Creation
mvn io.quarkus.platform:quarkus-maven-plugin:3.38.0:create \
-DprojectGroupId=com.example \
-DprojectArtifactId=quarkus-demo \
-Dextensions='resteasy-reactive,resteasy-reactive-jackson,hibernate-orm-panache,jdbc-postgresql'5.2 REST Endpoint
package com.example.resource;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
@Path("/hello")
public class GreetingResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "Hello from Quarkus!";
}
}5.3 Entity and Repository (Panache Style)
// Entity
@Entity
@Table(name = "products")
public class Product extends PanacheEntity {
public String name;
public BigDecimal price;
public Integer stock;
}
// Repository (Panache style, no implementation needed)
@ApplicationScoped
public class ProductRepository implements PanacheRepository<Product> {
public List<Product> findInStock() {
return find("stock > 0").list();
}
public List<Product> findByName(String name) {
return find("name", name).list();
}
}5.4 Service Layer
@ApplicationScoped
public class ProductService {
@Inject
ProductRepository productRepository;
public List<Product> getInStockProducts() {
return productRepository.findInStock();
}
@Transactional
public Product createProduct(Product product) {
product.persist();
return product;
}
}5.5 Configuration (application.properties)
quarkus.datasource.db-kind=postgresql
quarkus.datasource.username=postgres
quarkus.datasource.password=postgres
quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/mydb
quarkus.hibernate-orm.database.generation=update5.6 Running
# Dev mode (hot reload)
./mvnw quarkus:dev
# Package for JVM
./mvnw package
# Package as native image
./mvnw package -Pnative6. Pros and Cons
Pros
Revolutionary startup speed: JVM mode 1.3 s, Native mode 200 ms — shifts K8s scaling from minutes to seconds.
Drastically lower memory: Idle 88 MB, 2.5x less than Spring Boot. At 100 replicas, saves thousands of dollars monthly.
Build-time processing brings runtime determinism: Spring Boot's runtime flexibility (conditional bean registration) makes startup behavior unpredictable. Quarkus moves all decisions to build time; runtime behavior is fully determined.
Unified imperative and reactive programming model: Quarkus integrates both via Eclipse Vert.x while adhering to MicroProfile and Jakarta EE standards.
Excellent Dev Mode hot reload: Instant feedback on code, config, and resource changes without rebuild or restart.
Java 21 virtual threads as first-class citizens: Quarkus 4 baselines on Java 21; virtual threads get native support.
Production-ready Native Image: Designed from the ground up for build-time processing and GraalVM native compilation; the most mature Java framework for Native Image.
Cons
Ecosystem maturity lags Spring Boot: Community size and third-party integrations are smaller. Many internal enterprise middleware only provide Spring Boot starters.
Native Image engineering cost: Native builds are significantly slower; debugging native executables remains hard (requires GDB and debug symbols); not all Java features work out of the box.
Dynamic capabilities limited: Build-time processing restricts runtime dynamism. Libraries relying on runtime reflection may need extra configuration or adaptation.
Learning curve: Migrating from Spring Boot requires understanding a new programming model and DI mechanism (ArC), though standard APIs are compatible.
Kotlin support less mature: Quarkus' Kotlin integration is not as native or mature as Spring Boot's.
7. Applicable Scenarios
K8s Elastic Scaling Services: ✅✅✅ Strongly recommended — 200 ms startup makes scaling truly elastic.
Serverless/FaaS: ✅✅✅ Strongly recommended — startup moves from seconds to milliseconds.
High-Density Deployment: ✅✅✅ Strongly recommended — memory footprint half of Spring Boot.
AI Inference Services: ✅✅✅ Strongly recommended — fast startup + low latency suits model serving.
Financial Trading Systems: ✅✅✅ Strongly recommended — high throughput + low latency with stable response times.
Long-Running Core Services: ⚠️ Evaluate — startup advantage less significant; Spring Boot ecosystem more mature.
Heavy Spring Ecosystem Dependencies: ⚠️ Evaluate — migration cost may be high.
Kotlin-Centric Projects: ⚠️ Evaluate — Quarkus Kotlin support not as strong as Spring Boot.
8. Conclusion
Why are more people using Quarkus? Because it rethought the Java runtime model for the cloud-native era.
Spring Boot's philosophy is "runtime flexibility first," using reflection and scanning for developer convenience. That was the right choice for the monolith era.
In the Kubernetes era, startup time, memory footprint, and elastic scaling speed become hard constraints; the cost of the runtime reflection model becomes unacceptable.
Quarkus' philosophy is "build-time determinism first," moving all analysis to the build phase so runtime only executes pre-generated bytecode.
JVM mode 1.3 s startup, Native mode 200 ms startup — what do these numbers mean? They mean you can run Java on Serverless platforms, K8s scaling completes in seconds, and memory density doubles.
Quarkus is no silver bullet. Ecosystem maturity, Native Image engineering cost, and dynamic limitations are real drawbacks.
But for cloud-native scenarios — K8s elastic scaling, Serverless, high-density deployment — Quarkus is a production-verified, performance-leading, continuously evolving choice.
References
Quarkus Official Website: https://quarkus.io
Quarkus GitHub: https://github.com/quarkusio/quarkus
Source: Su San Says Tech
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
