from Inside


Peter Palaga


Peter Palaga


  • An 8 ms demo
  • What is Quarkus
  • How it works
  • More Quarkus



$ which docker # make sure you have docker
$ mvn clean package -Pnative -Dnative-image.docker-build
$ ls -lh target/*-runner
-rwxrwxr-x. 1 ppalaga ppalaga 19M Mar 20 14:39 target/quarkus-hello
$ ./target/*-runner
INFO  [io.quarkus] (main) Quarkus 0.28.0 started in 0.004s.
INFO  [io.quarkus] (main) Installed features: [cdi, resteasy]

What is Quarkus




for writing Java, Kotlin and Scala applications

Embracing existing standards

Java EE MicroProfile Spring
  • Servlet
  • JAX-RS
  • CDI
  • Bean Validation
  • Transactions
  • Fault Tolerance
  • Health
  • JWT
  • Metrics
  • OpenAPI
  • OpenTracing
  • Reactive Messaging
  • Rest Client
  • Spring DI1
  • Spring Web1
  • Spring Data1

1) via compatibility layers
Well established

Libs and frameworks

Eclipse Vert.x Netty Apache Camel Infinispan Caffeine Keycloak
Kubernetes AWS Lambda Azure Functions Apache Tika ElasticSearch Kogito


  • MySQL, MariaDB
  • PostgreSQL
  • MS SQL Server
  • H2
  • FlyWay
  • Amazon DynamoDB‎
  • MongoDB
  • Neo4j




SayService say;

public String hello() {
    return say.hello();
@Inject @Stream("kafka")
Publisher<String> reactiveSay;

public Publisher<String> stream() {
    return reactiveSay;

Developer joy

  • Easy to start with:
    mvn quarkus:create or
  • Live reload:
    mvn compile quarkus:dev
  • Runners for JUnit 5
  • Isolation from GraalVM CLI/API
  • Maven or Gradle
  • Java, Kotlin or Scala

Container First

💾 Small size on disk ✓ Small container images
🚀 Fast boot time ✓ Instant scale up
🔬 Low memory footprint ✓ More containers with the same RAM

Measuring memory

RSS1 = all RAM consumed by the process
$ ps -o pid,rss,command -p $(pgrep quarkus)
11229 12628 ./target/quarkus-hello


1) Resident Set Size

Memory (RSS)

Quarkus + GraalVM Quarkus + OpenJDK Traditional Cloud-Native Stack
REST 13 MB 74 MB 140 MB
REST+JPA 35 MB 130 MB 218 MB

Startup time

Modern frameworks use lazy initialization

"started" before all classes are initialzed

What matters:

Time to first request

 Time to first request


How it works

Traditional app server

  • 100s of classes run only during the boot
  • Later unused
  • Still occupy memory
  • Parse config files: XML, YAML, JSON, ...
  • Classpath scanning, esp. for annotations
  • Build framework metamodel objects
  • Prepare reflection and build proxies
  • Open sockets, start threads

Build time boot

As much work as possible done at build time

Output: recorded wiring bytecode

An example:

Build time CDI (1/2)

An example:

Build time CDI (2/2)

// User beans
class Catalog {

  Pricing pricing;

  void init() {}

class Pricing { ... }

// Metadata (generated as bytecode)
class Catalog_Bean {

  Pricing_Bean pricingBean;

  Catalog create() {
    Catalog catalog = new Catalog();
    catalog.pricing =
    return catalog;

class Pricing_Bean {...}

// The "main" class
// In reality generated as bytecode, here strongly simplified
class Application {
  static Map<String, Bean> beans = new ...Map();
  static Map<String, Supplier<Object>> appContext = new ...Map();
  static {
    // Wire the beans
    Pricing_Bean pricingBean = new Pricing_Bean();
    beans.put(Pricing_Bean.key, pricingBean);
    Catalog_Bean catalogBean = new Catalog_Bean();
    catalogBean.pricingBean = pricingBean;
    beans.put(Catalog_Bean.key, catalogBean);

    // Some beans can even be instantiated already
    Pricing pricing = pricingBean.create();
    appContext.put(Pricing_Bean.key, () -> pricing)
    Catalog catalog = catalogBean.create();
    appContext.put(Catalog_Bean.key, () -> catalog)

Wiring code invocation

Decided by extensions

static initializer OR main()
preferred access to files,
sockets, etc.

Build oriented container

Quarkus extensions

  • Units of Quarkus distribution (your Maven deps)
  • They configure, boot and integrate a lib/framework into a Quarkus application
  • Make the code lighter to run on a JVM
  • Make the code fit for the GraalVM

Quarkus Extensions ecosystem

  • New extensions are welcome!
  • Follow the guide for extension authors
  • Can be developed externally → Camel Quarkus
  • New: 3rd party extensions on and in the Quarkus universe BoM

Two distinct things:

  1. Graal compiler (AoT or JIT)
  2. GraalVM - the polyglot VM
In this presentation:



Graal compiler



AoT1 compilation with GraalVM

1) Ahead-of-time (1/3)

AoT compilation with GraalVM


  • Static analysis
  • Closed world assumption
  • Dead code elimination:
        classes, fields, methods, branches

AoT compilation with GraalVM


$ native-image -jar my-app.jar
$ ./my-app


GraalVM GraalVM

Dynaminc Classloading

Deloying jars, wars, etc. at runtime impossible

GraalVM GraalVM


+ other native VM interfaces

No agents

JRebel, Byteman, profilers, tracers, ...

GraalVM GraalVM


+ other native VM interfaces

  • No Java debugger
  • Native debugger (GDB) still works
  • DWARF debug symbols
    • Inserted only by GraalVM enterprise
    • Allows stepping through your java code
GraalVM GraalVM


Security Manager

finalize() (deprecated anyway)

InvokeDynamic and MethodHandles

GraalVM GraalVM


Requires registration via native-image CLI/API

@RegisterForReflection in Qarkus

GraalVM GraalVM


Require registration via native-image CLI/API

  • Dynamic proxies
  • Resources
  • JNI, Unsafe Memory Access, ...
GraalVM GraalVM

Static init


Build time OpenJDK instance:

  • Resolve classes, run "safe" static initilizers
  • Take a snapshot of the produced heap
  • Store it in the executable
GraalVM GraalVM

Static init



no file handles, sockets, threads

What Quarkus shields you from

$ native-image -jar my-app.jar \$BySpaceAndTime \
    -J-Djava.util.concurrent.ForkJoinPool.common.parallelism=1 \
    -H:FallbackThreshold=0 \
    -H:+ReportExceptionStackTraces \
    -H:+PrintAnalysisCallTree \
    -H:-AddAllCharsets \
    -H:EnableURLProtocols=http \
    -H:-JNI \
    -H:-UseServiceLoaderFeature \
    -H:+StackTrace \
    --no-server \
    --initialize-at-build-time=... \
    -J-Djava.util.logging.manager=org.jboss.logmanager.LogManager \
    -J-Dio.netty.leakDetection.level=DISABLED \
    -J-Dvertx.logger-delegate-factory-class-name=io.quarkus.vertx.core.runtime.VertxLogDelegateFactory \ \
    -J-Dio.netty.allocator.maxOrder=1 \

Performance tradeoffs

Performance tradeoofs JIT vs. AOT

Image source:

Efficiency through density

in cloud environments

More Quarkus!


  • export GRAALVM_HOME=...
  • Or use docker (on/for Linux)
$ mvn clean package -Dnative -Dnative-image.docker-build
$ ls -lh target/*-runner
-rwxrwxr-x. 1 ppalaga ppalaga 19M Mar 20 14:39 target/quarkus-hello
$ ./target/*-runner
INFO  [io.quarkus] (main) Quarkus 0.28.0 started in 0.005s.
INFO  [io.quarkus] (main) Installed features: [cdi, resteasy]

Discover extensions

$ mvn quarkus:list-extensions
[INFO] Available extensions:
[INFO]   * Hibernate ORM (io.quarkus:quarkus-hibernate-orm)
[INFO]   * Hibernate ORM with Panache (io.quarkus:quarkus-hibernate-orm-panache)
[INFO]   * Hibernate Validator (io.quarkus:quarkus-hibernate-validator)

Add an extension

$ mvn quarkus:add-extension -Dextensions=hibernate-orm-panache


Makes simple Hibernate ORM easy

public class Person extends PanacheEntity {
    public String name;
    public LocalDate birth;
    public PersonStatus status;

Panache persist

// Create a person
Person person = new Person(); = "Stef";
person.birth = LocalDate.of(1910, Month.FEBRUARY, 1);
person.status = Status.Alive;

// Persist and delete
if (person.isPersistent()){

Panache Queries

List<Person> allPersons = Person.listAll(); // All persons
Person p = Person.findById(personId); // Specific person by ID
// Living persons
List<Person> livingPersons = Person.list("status", Status.Alive);

// Count
int countAll = Person.count();
int countAlive = Person.count("status", Status.Alive);

// Delete
Person.delete("status", Status.Alive);

More Panache

  • Paging
  • Sorting
  • Simplified query language
  • Autogenerated DAO/Repositories

Quarkus wrap up


  • Good old Java
  • Good old standards and libs
  • Efficiency level of Go language


Makes Java the choice #1 for the cloud and serverless

Quarkus Links

Follow @QuarkusIO on Twitter!