Cloud Native 19 min read

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.

macrozheng
macrozheng
macrozheng
Why Quarkus Is Winning Cloud-Native Java: Build-Time Over Runtime Reflection

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 build-time architecture overview
Quarkus build-time architecture overview
Quarkus build-time processing flow
Quarkus build-time processing flow

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

Quarkus build-time vs Spring Boot runtime flow
Quarkus build-time vs Spring Boot runtime 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

Spring DI vs Quarkus ArC bean creation comparison
Spring DI vs Quarkus ArC bean creation comparison
ArC generated bytecode example
ArC generated bytecode example

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

Virtual thread vs platform thread scheduling
Virtual thread vs platform thread scheduling
Virtual thread scheduling detail
Virtual thread scheduling detail

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=update

5.6 Running

# Dev mode (hot reload)
./mvnw quarkus:dev

# Package for JVM
./mvnw package

# Package as native image
./mvnw package -Pnative

6. 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
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Javacloud-nativePerformance BenchmarkSpring BootQuarkusVirtual ThreadsNative ImageBuild-Time Processing
macrozheng
Written by

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.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.