Upgrade to Pro — share decks privately, control downloads, hide ads and more …

The ROI of Quarkus for Spring Boot Applications

The ROI of Quarkus for Spring Boot Applications

Quarkus applications are quick to code, start fast, and require much less hardware than their Spring Boot equivalents. They use less memory, less electricity, and handle much higher load. They make both developers and LLMs more productive, saving both time and tokens. So can we quantify the financial benefits of switching from Spring Boot to Quarkus? Yes. (Spoiler – it’s good!) In this talk, Holly will explain the architectural choices which make Quarkus fast. She’ll explain how to choose between JVM and native run modes, depending what kind of “fast” you need. Finally, she’ll demonstrate options for getting from Spring to Quarkus quickly and cheaply, for a near-immediate return on investment.

Avatar for Holly Cummins

Holly Cummins

June 01, 2026

More Decks by Holly Cummins

Other Decks in Programming

Transcript

  1. Sanil Nambiar Session APD23 | June 2nd, 2026 Holly Cummins,

    STSM, Quarkus The ROI of Quarkus for Spring Boot Applications
  2. Agenda -What is Quarkus? -Why Quarkus? -Can we quantify that?

    -The developer experience ROI -Getting to Quarkus from Spring Boot
  3. @holly_cummins #Quarkus “I can’t bring up the microservices in my

    Java dev stack … on my brand new Apple laptop with a M1 chip and - fi ntech CTO 2022
  4. @holly_cummins #Quarkus in production, it’s worse example microservices maths: Lufthansa

    maintenance scheduling system single service: ½ core + 1 GB RAM
  5. @holly_cummins #Quarkus in production, it’s worse example microservices maths: Lufthansa

    maintenance scheduling system single service: ½ core + 1 GB RAM HA → 3x instances
  6. @holly_cummins #Quarkus in production, it’s worse example microservices maths: Lufthansa

    maintenance scheduling system single service: ½ core + 1 GB RAM HA → 3x instances ~100 microservices
  7. @holly_cummins #Quarkus in production, it’s worse example microservices maths: Lufthansa

    maintenance scheduling system single service: ½ core + 1 GB RAM HA → 3x instances ~100 microservices = 150 cores + 300 GB RAM
  8. netty etc runtime infrastructure build infrastructure hibernate rest langchain4j jackson

    - An integrated collection of your favourite libraries (Hibernate, Jackson, dependency injection, Netty, etc) - A super-scalable core, build on Eclipse Vert.x - Minimises unnecessary work at runtime
  9. netty etc runtime infrastructure build infrastructure hibernate rest langchain4j jackson

    - An integrated collection of your favourite libraries (Hibernate, Jackson, dependency injection, Netty, etc) - A super-scalable core, build on Eclipse Vert.x - Minimises unnecessary work at runtime
  10. e ffi ciency developer experience (also e ffi ciency) build-time

    principle reactive core live reload continuous testing
  11. e ffi ciency developer experience (also e ffi ciency) build-time

    principle reactive core minimising boilerplate live reload continuous testing
  12. e ffi ciency developer experience (also e ffi ciency) build-time

    principle reactive core minimising boilerplate live reload continuous testing dev ui
  13. e ffi ciency developer experience (also e ffi ciency) build-time

    principle reactive core minimising boilerplate live reload continuous testing dev ui
  14. e ffi ciency developer experience (also e ffi ciency) build-time

    principle reactive core minimising boilerplate live reload continuous testing dev ui
  15. @holly_cummins #Quarkus how does a java framework start? </> build

    time runtime load and parse • config files • properties • yaml • xml • etc.
  16. @holly_cummins #Quarkus how does a java framework start? @ @

    </> build time runtime • classpath scanning and annotation discovery • attempt to load class to enable/disable features
  17. @holly_cummins #Quarkus how does a java framework start? @ @

    </> build time runtime build a metamodel of the world
  18. @holly_cummins #Quarkus how does a java framework start? @ @

    </> build time runtime start • thread pools • I/O • etc.
  19. @holly_cummins #Quarkus how does a java framework start? @ @

    </> build time runtime ready to do work!
  20. @holly_cummins #Quarkus what if we start the application more than

    once? @ @ </> @ @ </> @ @ </> @ @ </> so much work gets redone every time
  21. @holly_cummins JVM spends time loading classes for specific databases JVM

    class for unused database class for unused database class for unused database class for unused database class for unused database class for unused database class for unused database class for unused database class for unused database class for unused database class for unused database class for unused database class for unused database class for unused database class for unused database class for unused database footprint example: Hibernate
  22. @holly_cummins JVM spends time loading classes for specific databases JVM

    class for unused database class for unused database class for unused database class for unused database class for unused database class for unused database class for unused database class for unused database class for unused database class for unused database class for unused database class for unused database class for unused database class for unused database class for unused database class for unused database turns out they’re never used footprint example: Hibernate
  23. @holly_cummins JVM spends time loading classes for specific databases JVM

    turns out they’re never used JIT spends time unloading classes footprint example: Hibernate
  24. @holly_cummins Hibernate example: ~500 classes which are only useful if

    you're running an Oracle database loaded and then unloaded
  25. @holly_cummins Hibernate example: ~500 classes which are only useful if

    you're running an Oracle database loaded and then unloaded every single start.
  26. @holly_cummins unused implementation the one we want interface unused implementation

    unused implementation the true cost of loaded classes isn’t just memory + start time method dispatching:
  27. @holly_cummins unused implementation the one we want interface unused implementation

    unused implementation the true cost of loaded classes isn’t just memory + start time method dispatching:
  28. @holly_cummins unused implementation the one we want interface megamorphic call

    slow dispatching unused implementation unused implementation the true cost of loaded classes isn’t just memory + start time method dispatching:
  29. @holly_cummins the true cost of loaded classes isn’t just memory

    + start time the one we want monomorphic call fast dispatching interface
  30. @holly_cummins #Quarkus @ @ </> build time runtime start •

    thread pools • I/O • etc. what if we initialize at build time?
  31. @holly_cummins #Quarkus @ @ </> build time runtime ready to

    do work! start • thread pools • I/O • etc. what if we initialize at build time?
  32. #Quarkus @holly_cummins hey, wanna see quarkus? hey, wanna see quarkus?

    hey, wanna see quarkus? hey, wanna see quarkus? hey, wanna see quarkus? 2020
  33. #Quarkus @holly_cummins hey, wanna see quarkus? hey, wanna see quarkus?

    hey, wanna see quarkus? hey, wanna see quarkus? hey, wanna see quarkus? uhh … are you supposed to shut down applications after using them? 2020
  34. #Quarkus @holly_cummins hey, wanna see quarkus? hey, wanna see quarkus?

    hey, wanna see quarkus? hey, wanna see quarkus? hey, wanna see quarkus? uhh … are you supposed to shut down applications after using them? 120 instances (!) 2020
  35. @holly_cummins doing more up-front - speeds up start - shrinks

    memory footprint - improves throughput (!)
  36. low load pack many instances onto a node memory is

    the limiting factor how much hardware does an app need? high load horizontally scale to support load max throughput is the limiting factor
  37. quarkus spring p r i 0.17 p r i 1489.2

    assumptions: EC2 c6i.xlarge instance, us-east-1, $0.17 per hour low load scenario: cost per instance per year
  38. quarkus spring p r i 0.17 p r i 1489.2

    jvm US$64.75 US$135.38 assumptions: EC2 c6i.xlarge instance, us-east-1, $0.17 per hour low load scenario: cost per instance per year
  39. quarkus spring p r i 0.17 p r i 1489.2

    jvm US$64.75 US$135.38 native US$19.86 US$64.75 assumptions: EC2 c6i.xlarge instance, us-east-1, $0.17 per hour low load scenario: cost per instance per year
  40. quarkus spring p r i 0.17 p r i 1489.2

    jvm US$64.75 US$135.38 native US$19.86 US$64.75 assumptions: EC2 c6i.xlarge instance, us-east-1, $0.17 per hour low load scenario: cost per instance per year 2.1x
  41. quarkus spring p r i 0.17 p r i 1489.2

    jvm US$64.75 US$135.38 native US$19.86 US$64.75 assumptions: EC2 c6i.xlarge instance, us-east-1, $0.17 per hour low load scenario: cost per instance per year 2.1x 3.3x
  42. p r i p r i jvm native quarkus 0.17

    1489.2 US$6,475 US$1,986 spring US$13,538 US$6,475 low load scenario: cost per hundred instances per year assumptions: EC2 c6i.xlarge instance, us-east-1, $0.17 per hour
  43. 10,000 tps 20,000 tps 30,000 tps machine 15,000 tps machine

    15,000 tps machine 15,000 tps machine 15,000 tps machine 15,000 tps
  44. 10,000 tps 20,000 tps 30,000 tps 40,000 tps machine 15,000

    tps machine 15,000 tps machine 15,000 tps machine 15,000 tps machine 15,000 tps
  45. 10,000 tps 20,000 tps 30,000 tps 40,000 tps machine 15,000

    tps machine 15,000 tps machine 15,000 tps machine 15,000 tps machine 15,000 tps machine 15,000 tps machine 15,000 tps machine 15,000 tps
  46. low load quarkus native uses ⅓ the memory of spring

    native how much can quarkus save you? high load quarkus on jvm can handle 1.7x more requests than spring boot
  47. @holly_cummins #Quarkus remember the airline scheduling application? “[With Quarkus], we

    can run 3 times denser deployments without sacrificing availability and response times of services. ” – Thorsten Pohl
  48. @holly_cummins #Quarkus remember the airline scheduling application? “[With Quarkus], we

    can run 3 times denser deployments without sacrificing availability and response times of services. ” – Thorsten Pohl 3x less hardware
  49. @holly_cummins #RedHat Setup: • REST + CRUD • large heap

    • RAPL energy measurement • multiple instances to support high load
 Assumptions: • US energy mix Source: John O’Hara experiment 1: RAPL measurements
  50. @holly_cummins #RedHat Setup: • REST + CRUD • large heap

    • RAPL energy measurement • multiple instances to support high load
 Assumptions: • US energy mix Source: John O’Hara experiment 1: RAPL measurements quarkus on JVM has the lowest carbon … because it has the highest throughput
  51. @holly_cummins #RedHat Setup: • REST + CRUD • large heap

    • RAPL energy measurement • multiple instances to support high load
 Assumptions: • US energy mix Source: John O’Hara experiment 1: RAPL measurements quarkus on JVM has the lowest carbon … because it has the highest throughput ~½ the energy requirements
  52. @holly_cummins #RedHat density Source: Clement Esco ff i er experiment

    2: cloud Setup: • 800 requests/second, over 20 days • SLA > 99% • AWS instances Assumptions: • Costs are for us-east-1 data centre
  53. @holly_cummins #RedHat interpolated carbon metrics – hardware and electricity Setup:

    • 800 requests/second, over 20 days • SLA > 99% Assumptions: • 50% load Source: Clement Esco ffi er x Teads cloud carbon impact of framework choice
  54. @holly_cummins #RedHat interpolated carbon metrics – hardware and electricity Setup:

    • 800 requests/second, over 20 days • SLA > 99% Assumptions: • 50% load Source: Clement Esco ffi er x Teads cloud carbon impact of framework choice the carbon is lower because the cost is lower
  55. @holly_cummins #RedHat interpolated carbon metrics – hardware and electricity Setup:

    • 800 requests/second, over 20 days • SLA > 99% Assumptions: • 50% load Source: Clement Esco ffi er x Teads cloud carbon impact of framework choice the carbon is lower because the cost is lower ~½ the carbon
  56. @holly_cummins #Quarkus tests are run on every code change “reverse

    code coverage” means only relevant tests run mvn quarkus:dev continuous testing
  57. @holly_cummins #Quarkus testcontainers integration … without quarkus @TestConfiguration(proxyBeanMethods = false)

    public class ContainersConfig { @Bean @ServiceConnection public PostgreSQLContainer<?> postgres() { return new PostgreSQLContainer<>(DockerImageName.parse("postgres:14")); } } public class TestApplication { public static void main(String[] args) { SpringApplication .from(MySpringDataApplication::main) .with(ContainersConfig.class) .run(args); } } @Import(ContainersConfig.class)
  58. @holly_cummins #Quarkus zero-config testcontainers integration the only thing you need

    to do to make testcontainers work is not con fi gure anything # configure your datasource quarkus.datasource.db-kind = postgresql quarkus.datasource.username = sarah quarkus.datasource.password = connor quarkus.datasource.jdbc.url = jdbc:postgresql://localhost:5432/mydatabase # drop and create the database at startup quarkus.hibernate-orm.database.generation = drop-and-create
  59. @holly_cummins #Quarkus zero-config testcontainers integration the only thing you need

    to do to make testcontainers work is not con fi gure anything # drop and create the database at startup quarkus.hibernate-orm.database.generation = drop-and-create
  60. @holly_cummins #Quarkus zero-config testcontainers integration the only thing you need

    to do to make testcontainers work is not con fi gure anything
  61. @holly_cummins #Quarkus zero-config testcontainers integration the only thing you need

    to do to make testcontainers work is not con fi gure anything quarkus also auto-invokes fl yway and liquibase
  62. @holly_cummins #Quarkus @ApplicationScoped public class GreetingRepository { public Entity findByName(int

    name) { return find("name", name).firstResult(); } void persist(Entity entity) {} void delete(Entity entity) {} Entity findById(Id id) {} List<Entity> list(String query, Sort sort, Object... params) { return null; } Stream<Entity> stream(String query, Object... params) { return null; } long count() { return 0; } long count(String query, Object... params) { return 0; } } example: panache + hibernate
  63. @holly_cummins #Quarkus example: panache + hibernate @ApplicationScoped public class GreetingRepository

    implements PanacheRepository<Greeting> { public Entity findByName(int name) { return find("name", name).firstResult(); } }
  64. @holly_cummins #Quarkus DAO example: panache + hibernate @ApplicationScoped public class

    GreetingRepository implements PanacheRepository<Greeting> { public Entity findByName(int name) { return find("name", name).firstResult(); } } repository pattern
  65. @holly_cummins #Quarkus example: panache + hibernate active record pattern @Entity

    public class Greeting extends PanacheEntity { public String name; public LocalDate issued; @Version public int version; public static List<Greeting> getTodaysGreetings() { return list("date", LocalDate.now()); } }
  66. 2019: Moved digital experience to quarkus (from Spring Boot) Christos

    Sotiriou, DXL technical lead at Vodafone Greece
  67. 2019: Moved digital experience to quarkus (from Spring Boot) •

    Startup times 40s ➡ 12s Christos Sotiriou, DXL technical lead at Vodafone Greece
  68. 2019: Moved digital experience to quarkus (from Spring Boot) •

    Startup times 40s ➡ 12s • RAM 800 MB ➡ 360 MB Christos Sotiriou, DXL technical lead at Vodafone Greece
  69. 2019: Moved digital experience to quarkus (from Spring Boot) •

    Startup times 40s ➡ 12s • RAM 800 MB ➡ 360 MB • Developer productivity ⬆ 30-40%– Christos Sotiriou, DXL technical lead at Vodafone Greece
  70. 2019: Moved digital experience to quarkus (from Spring Boot) •

    Startup times 40s ➡ 12s • RAM 800 MB ➡ 360 MB • Developer productivity ⬆ 30-40%– 30-40% more productive Christos Sotiriou, DXL technical lead at Vodafone Greece
  71. @holly_cummins #Quarkus “After a week of development with Quarkus, I

    was able to regain the same level of productivity as when I was developing with Spring Boot.” – Fawaz Paraïso, Decathlon
  72. @holly_cummins #Quarkus tl;dpa (too long didn’t pay attention) deployment density

    lower cloud bill frictionless development experience Medium Nano auto-provision services zero-con fi g live coding continuous testing developer UI greener happy, productive people
  73. @holly_cummins #Quarkus stl;dpa (still too long didn’t pay attention) e

    ffi ciency quarkus can be packed ~2x more densely than spring boot quarkus can handle ~2x more tra ffi c on the same hardware developer experience quarkus creates joy quarkus boosts productivity by
  74. @holly_cummins #Quarkus stl;dpa (still too long didn’t pay attention) e

    ffi ciency quarkus can be packed ~2x more densely than spring boot quarkus can handle ~2x more tra ffi c on the same hardware developer experience quarkus creates joy quarkus boosts productivity by 2x less infra
  75. @holly_cummins #Quarkus stl;dpa (still too long didn’t pay attention) e

    ffi ciency quarkus can be packed ~2x more densely than spring boot quarkus can handle ~2x more tra ffi c on the same hardware developer experience quarkus creates joy quarkus boosts productivity by 40% more productive 2x less infra