#81: Quarkus: supersonic, subatomic Java (guest: Holly Cummins)
Author: Holly Cummins
Quarkus is supersonic, subatomic Java. What does that mean? It means it’s Java, but really, really small. And really, really fast. Quarkus is a runtime framework which gives you access to programming models you’re probably familiar with. Like Microprofile, JAX-RS, CDI dependency injection. And also access you’re probably less familiar with, like reactive programming.
Quarkus can run in two modes. On the JVM, like a normal framework. Or compiled to a native binary using GraalVM. In JVM mode Quarkus has about half the memory footprint of a traditional cloud-native framework. And the app starts about four times faster. And it achieves that small footprint without sacrificing throughput. In fact, it’s the opposite.
I’m a software engineer helping to build Quarkus. And in my team’s performance experiments Quarkus runtime speed is better than with a traditional cloud native framework. What I mean by that is that throughput is higher with Quarkus.
If you compile your Quarkus app into the native mode, which is just a maven flag, with no code changes, then the footprint is a tenth of the traditional cloud native. And the REST app will start and service the first request in 0.016 seconds. That’s faster than an LED lightbulb. With the native mode, there is a bit of a tradeoff against runtime performance. So that ridiculously instantaneous startup speed means your throughput is going to be a little bit less in Quarkus native mode than you would see in Quarkus JVM mode.
The fast speed and small size of Quarkus (and high throughput of course) have a lot of practical benefits. And it has cost benefits. And sustainability benefits. Quarkus uses fewer resources, and that means it uses less power and that means fewer greenhouse gases.
So what’s the catch? Quarkus is lean at runtime because it does more upfront at build time. Figuring out what’s going on with your application at build time requires the application to be a closed world. If you’re doing a lot of reflection and custom libraries, you need to do some configuration work to bring those reflective accessed classes into the closed world. So they don’t get optimized away as unused.
The good news is that reflection mostly happens in libraries. And Quarkus comes with extensions for all the popular libraries to make sure they work perfectly in that closed world. As a bonus, the Quarkus extension for the library often gives a better user experience than a vanilla library.
My favourite part is something called Dev Services. A lot of extension libraries will stand up an instance of that library for testing and local development. For example, if you don’t explicitly configure an external Postgres database, when you run your Quarkus application that uses Postgres in Dev mode, Quarkus will stand up a Postgres database for you using testcontainers and wire your application to that database.
Quarkus’ developer mode has a few other nice tricks. There’s a live reload so that you can edit your code, even in a text editor, so it’s not an IDE thing. And it’ll be instantly available to play within the application. Dev mode also runs your test automatically and continuously. Fast feedback is so important for developers.
But if you have a huge test suite running continuously every time you change that line of code, that’s not fast feedback. Quarkus fixes that problem by working out what code affects what tests. It’s sort of like reverse code coverage. And it runs only those tests that could break as a result of your code changes. The Quarkus team calls these features “developer joy”. And I think that’s something we can all aspire to.