Why I use Quarkus rather than Spring-Boot for my CNA apps

Dernière mise à jour : 8 sept. 2021


This post demonstrates the advantages of compiling and running a Java application using Quarkus.

As an introduction about what is Quarkus you can read the previous blog post written by Yann Albou.


Photo by Shiro Hatori on Unsplash

To get the most out of your application in the Cloud and especially in containers and Kubernetes you need to design your application for this new world. How can frameworks help to reach high levels of productivity and efficiency ?

For sure Java frameworks can help in the area, either Spring Boot or Quarkus, that we compare in this article using the same sample application.

The code used is available on GitHub, you can find three subdirectories:

  • employee-sb - Spring Boot flavor

  • employee-quarkus - Quarkus version

  • comparisons - tools for comparing the application on both platforms

The sample application is a simple CRUD of a root entity "Persons", connected to a Postgres database. We use the Hibernate ORM for both applications, and additionally the Panache framework in case of Quarkus.

There are two ways for compiling a Java application using the Quarkus framework:

  • standard / old-fashioned JVM

  • GraalVM (for generation of native code)

To get a minimalistic exposed surface in terms of security, we will use scratch as the starting point of our Docker image, to get only our application binary in it.


Environment Setup

To avoid complex setup with GraalVM, you can use a multistage Docker build, which helps in building the GraalVM binary without installing it locally.

The multistage Docker build is composed of three stages (see Dockerfile.scratch.native):

  • collect jar dependencies in the first step, to avoid losing time in the following steps

  • build the native binary (some tricks are necessary when using a scratch or an alpine image, detailed in the Dockerfile comments)

  • finally, copy the binary into our scratch image

In both subdirectories employee-sb and employee-quarkus you can find a build-mvn-docker script that builds images for you, and then tag the docker image with the name that will be used by the comparison tools.

The hardware used for comparisons is a MacBook Pro laptop with Docker Desktop installed on it to run the containers.

Dedicated resources for Docker Virtual Machine are:

  • 8Gb of RAM + 1Gb for swap.

  • 8 CPUs.

Benchmark

In order to compare various approaches, we have a look at 3 key metrics:

  • startup time

  • size of generated artifacts and docker image

  • memory usage

Startup time

Spring Boot - Startup time: ~10 seconds

  • Old-fashioned

  • Less efficient than Quarkus

Quarkus JVM - Startup time: ~2-3 seconds

  • Simple build without -Dnative (or -Pnative, the choice is yours)

  • Less efficient than a native build

  • More efficient than a classic stack

Quarkus native - Startup time < 0.1 second as shown above

  • Very efficient

  • Compilation time is slow since you use GraalVM, but it’s the price to pay to have great performances at runtime. Notice that if you use multistage build, your build time will be slower than in the “standard GraalVM way”.


Size of JAR files


If you analyze the generated jar file from Quarkus, you see there’s no lib (JAR files) included, every class needed at runtime is extracted from its original library and included in the generated jar d