Part 8 · 1 chapters · ~8 min
Quarkus and Native Images
Why start-up time and memory matter (containers, serverless, scale to zero), Quarkus's build-time processing and ArC dependency injection, dev mode and continuous testing, RESTEasy Reactive and Panache, GraalVM native images and their constraints, Spring AOT and CRaC, and choosing between Spring Boot and Quarkus.
11
Quarkus in practice
code
@Path("/v1/transfers")
public class TransferResource {
@Inject TransferService service;
@POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public Response create(@Valid CreateTransfer in, @HeaderParam("Idempotency-Key") String key) {
return Response.status(201).entity(service.create(in, key)).build();
}
}
// Panache: active-record style entities
@Entity public class Account extends PanacheEntity { public String currency; public long balanceKobo; }
./mvnw quarkus:dev # live reload + continuous testing
./mvnw package -Dnative # GraalVM native binary (needs GraalVM or a builder image)
./target/ledger-1.0-runner # starts in tens of milliseconds| choose | when |
|---|---|
| Spring Boot | the largest ecosystem, team familiarity, long-running services, Spring Cloud integrations |
| Quarkus (JVM) | faster start and lower memory with standard Jakarta APIs, Kubernetes-native tooling |
| Quarkus native | serverless, scale-to-zero, many small services where RSS and start-up dominate cost |
QUARKUS: MOVE THE WORK TO BUILD TIME
what Spring does at every start, Quarkus does once at build
swipe the figure sideways, or tap expand for full screen
1/5
build-time processing
Quarkus extensions run at build time: they scan annotations, resolve dependency injection (ArC), and generate the bytecode that wires the app. At run time there is little left to discover.
DI and scanning done at build timeArC: build-time CDI