Quarkus Vs Micronaut: A Feature And Performance Comparison
Quarkus and Micronaut are modern Java frameworks that can be used to build microservice and serverless applications tailored for JDK and GraalVM.
While Quarkus is backed by Red Hat, Micronaut is developed by the creators of the Grails framework and sponsored by Object Computing, Inc..
Development of Quarkus started on early 2019, the 1.0.0 version was released on November 2019. Micronaut development started on early 2018, the 1.0.0 version was released on October 2018.
Both Quarkus and Micronaut are open source under the Apache License 2.0.
While Quarkus is more reliant on Java EE and Eclipse MicroProfile APIs, Micronaut defines it's own APIs and is more inspired by the Spring and Grails frameworks.
Quarkus is based on an extension architecture that makes it easy to integrate third party frameworks. You can for example use Spring DI, Web and Data JPA annotations in your Quarkus applications.
Micronaut provides an Aspect Oriented Programming (AOP) implementation that does not use reflection to define cross cutting concerns (logging, ...).
Dependency Injection and Inversion of Control
Quarkus implements a subset of the Contexts and Dependency Injection (CDI) specification. Supported DI features and limitation can be viewed here.
Micronaut uses a simpler compile time dependency injection implementation that only uses reflection as a last resort and avoids proxies. A full Micronaut IoC guide is available in this page.
Reactive and declarative programming
Both Quarkus and Micronaut support reactive programming.
Quarkus supports both Netty and Vert.x as reactive engines that are based on an event-driven architecture with non-blocking IO. Reactive Messaging is supported with Apache Kafka and AMQP. Reactive MySQL, PostgreSQL and MongoDB clients are also available. An alternative declarative way to implement HTTP endpoints is possible with Reactive routes.
Micronaut includes both non-blocking HTTP server and client APIs based on Netty. Reactive MySQL and PostgreSQL clients are supported via third-party libraries. Apache Kafka and RabbitMQ are also supported with Reactive APIs.
Resilience & Fault tolerance
To enable resiliency, Quarkus contains an implementation of the MicroProfile Fault Tolerance specification to provide Retry, Timeout, Fallback, and Circuit Breaker capabilities (as demonstrated in the following guide).
Micronaut also supports the Retry, Fallback, and Circuit Breaker patterns as AOP advices.
Quarkus primarily targets Kubernetes cloud environments. Automated generation of Kubernetes resources is provided out of the box. Experimental serverless support is available for AWS Lambda and Azure Functions.
Micronaut provides natively support to many cloud features:
- Distributed Configuration with:
- HashiCorp Consul
- HashiCorp Vault
- Spring Cloud Config
- AWS Parameter Store
- Service Discovery with:
- AWS Route 53
- Serverless Functions: many features are provided to make it easier to write functions, run and deploy them to Function as a Service (FaaS) providers such as AWS Lambda or dedicated containers such as OpenFaaS.
While Quarkus provides support to Java, Kotlin and Scala, Micronaut comes with for Java, Groovy and Kotlin support.
Kotlin is a cross-platform statically typed language that is highly interoperable with existing Java libraries and allows writing concise code. It's also the official language for Android app development.
Scala is a multi-paradigm language with a strong static type system that provides language interoperability with Java and offers a more elegant code syntax.
Groovy is a dynamic and optionally typed JVM language with static compilation capabilities that aims to provide an easy to learn syntax.
Quarkus provides an online project generator with configurable dependencies: https://code.quarkus.io/. It also provides live reload capabilities for the GraalVM native build mode.
Micronaut projects can also be generated with an online generator: https://micronaut.io/launch/.
Performance & Benchmarks (JDK 14)
Both the Quarkus and Micronaut demo apps are minimal and expose a simple hello endpoint. For those interested, the source code of the demo apps can be found here: quarkus-hello-demo, micronaut-hello-demo.
Time to first request
You can find the script used to collect the time to first request in the following repository.
On this example, Quarkus has on average two times shorter time to first request then Micronaut.
Quarkus had almost 20% higher request per second using the loadtest tool.
Quarkus had on average a 66% higher request per second and lower latencies when using the wrk tool.
The VisualVm tool was used to monitor the memory usage of both demo apps after starting them up and executing 10000 requests, then performing a GC manually.
In this example, Quarkus uses less memory then Micronaut:
- 33 MB min memory usage after GC for Micronaut vs 12 MB for Quarkus
- 50 MB max memory usage for Micronaut vs 24 MB for Quarkus
This can be explained by the lower loaded classes.
When it comes to features, both frameworks provide comparable serverless and cloud capabilities with a wide array of third-party library integrations, and support both imperative and reactive stacks.
Performance-wise, Quarkus had better base memory footprint, lower time to first request and higher simple request throughput with simple hello demo apps. These criteria are essential when using auto-scaled microservice apps, and negligible for monolith apps.
For even more performance gains, the next step would be to consider compiling your app natively using GraalVM Native Image. I have found that Quarkus provides better Native Image support than Micronaut in my simple experiments. I have shared in this article some tips to help you get started with the GraalVM Native Image tool.
Soufiane Sakhi is an AWS Certified Solutions Architect – Associate and a professional full stack developer based in Paris, France. He is the creator of Simply-how.com, the My Route Directions Android app, and many open source browser extensions such as YouTube Playlist Helper and Feedly filtering and sorting.