Quarkus vs Spring Boot
What is Quarkus ?
- Quarkus is a Kubernetes-native Java framework designed for building high-performance, cloud-native, and serverless applications. It is optimized for fast startup times, low memory usage, and seamless integration with containers.
Key Features of Quarkus:
Supersonic & Subatomic: Super-fast startup times (milliseconds) and a tiny memory footprint
✅ Cloud & Kubernetes Native: Optimized for running in containers and serverless environments
✅ Developer-Friendly: Live coding, fast reloads, and easy configuration
✅ Works with JVM & Native: Runs efficiently on traditional JVM and compiles natively with GraalVM
✅ Built for Modern Architectures: Supports reactive programming, microservices, and event-driven applications
✅ Rich Ecosystem: Compatible with Hibernate, RESTEasy, Kafka, OpenTelemetry, and more
Why Use Quarkus?
- Ideal for Microservices: Perfect for cloud-based, microservices-driven architectures
- Ultra-Fast Performance: Starts up in milliseconds, ideal for scaling dynamically
- Reduced Infrastructure Costs: Uses less memory and CPU, saving cloud costs
- Improves Developer Productivity: Hot reload, Dev UI, and powerful tooling
Setting up application
- Go to https://code.quarkus.io/
- Generate the project
- Unzip the jar
- Open the project in Intellij Idea

build.gradle
plugins {
id 'java'
id 'io.quarkus'
}
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")
implementation 'io.quarkus:quarkus-resteasy'
implementation 'io.quarkus:quarkus-resteasy-jackson'
implementation 'io.quarkus:quarkus-arc'
testImplementation 'io.quarkus:quarkus-junit5'
testImplementation 'io.rest-assured:rest-assured'
}
group 'org.acme'
version '1.0.0-SNAPSHOT'
java {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
test {
systemProperty "java.util.logging.manager", "org.jboss.logmanager.LogManager"
}
compileJava {
options.encoding = 'UTF-8'
options.compilerArgs << '-parameters'
}
compileTestJava {
options.encoding = 'UTF-8'
}


Try Live Reloading
Build and Run Jar
- The application can be packaged using:
- In case if test task is failing change the set the following property in application.properties
- It produces the
quarkus-run.jarfile in thebuild/quarkus-app/directory.
- The application is now runnable using
./gradlew buildjava -jar build/quarkus-app/quarkus-run.jarquarkus.http.test-port=9001Create and Run docker image of a quarkus app
docker build -f src/main/docker/Dockerfile.jvm -t my-q-app .Build the image
Run the container from the image
docker container run -p 8080:8080 --name quarkus-app -d my-q-appCompare quarkus app with spring boot app using jconsole
Simple Crud Operations
package org.acme;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Path("/mobiles")
public class MobileResource {
List<String> mobiles = new ArrayList<>(Arrays.asList("iPhone", "Samsung", "OnePlus"));
@GET
@Produces(MediaType.TEXT_PLAIN)
public Response getMobile() {
return Response.ok(mobiles).build();
}
@POST
@Consumes(MediaType.TEXT_PLAIN)
public Response saveMobile(String mobileName) {
mobiles.add(mobileName);
return Response.ok(mobiles).build();
}
@PUT
@Consumes(MediaType.TEXT_PLAIN)
public Response updateMobile(@QueryParam("oldName") String oldName, @QueryParam("newName") String newName) {
int index = mobiles.indexOf(oldName);
mobiles.set(index, newName);
return Response.ok(mobiles).build();
}
@DELETE
@Path("/{name}")
@Consumes(MediaType.TEXT_PLAIN)
public Response deleteMobile(@PathParam("name") String name) {
mobiles.remove(name);
return Response.ok(mobiles).build();
}
}

List Extensions
Add Quarkus Extension



Access the swagger UI http://localhost:8080/q/swagger-ui
Microprofile Rest Client

plugins {
id 'java'
id 'io.quarkus'
}
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
implementation 'io.quarkus:quarkus-smallrye-fault-tolerance'
implementation 'io.quarkus:quarkus-smallrye-openapi'
implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")
implementation 'io.quarkus:quarkus-resteasy'
implementation 'io.quarkus:quarkus-resteasy-jackson'
implementation 'io.quarkus:quarkus-arc'
implementation 'io.quarkus:quarkus-resteasy-client-jackson'
testImplementation 'io.quarkus:quarkus-junit5'
testImplementation 'io.rest-assured:rest-assured'
}
group 'org.acme'
version '1.0.0-SNAPSHOT'
java {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
test {
systemProperty "java.util.logging.manager", "org.jboss.logmanager.LogManager"
}
compileJava {
options.encoding = 'UTF-8'
options.compilerArgs << '-parameters'
}
compileTestJava {
options.encoding = 'UTF-8'
}
package org.acme;
import java.net.URL;
public class TvSeries {
private int id;
private URL url;
private String name;
private String type;
private String language;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public URL getUrl() {
return url;
}
public void setUrl(URL url) {
this.url = url;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
}
package org.acme;
import jakarta.json.JsonArray;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.QueryParam;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import java.util.List;
@RegisterRestClient(baseUri = "https://api.tvmaze.com")
public interface TvSeriesProxy {
//https://api.tvmaze.com/shows/169
@GET
@Path("/shows/{id}")
TvSeries getTvSeriesById(@PathParam("id") int id);
@GET
@Path("/search/people")
List<Object> searchPeople(@QueryParam("q") String query);
}
package org.acme;
import jakarta.json.JsonArray;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import java.util.List;
@Path("/tvseries")
public class TvSeriesResource {
@RestClient
TvSeriesProxy tvSeriesProxy;
@GET
@Path("/{id}")
public TvSeries getTvSeriesById(@PathParam("id") int id) {
return tvSeriesProxy.getTvSeriesById(id);
}
@GET
@Path("/search/{name}")
public List<Object> getTvSeriesByName(@PathParam("name") String name) {
List<Object> tvSeries = tvSeriesProxy.searchPeople(name);
System.out.println(tvSeries);
return tvSeries;
}
}
Fault tolerance
Extension needed for fault tolerance : quarkus-smallrye-fault-tolerance
@GET
@Fallback(
fallbackMethod = "fallback",
applyOn = {RuntimeException.class} ,
skipOn = {IllegalArgumentException.class}
)
@Path("/{id}")
public Response getTvSeriesById(@PathParam("id") int id) {
return Response.ok(tvSeriesProxy.getTvSeriesById(id)).build();
}
public Response fallback(int id) {
return Response.ok("Site is under maintainance").build() ;
}@GET
@Fallback(
fallbackMethod = "fallback",
applyOn = {RuntimeException.class} ,
skipOn = {IllegalArgumentException.class}
)
@Retry(maxRetries = 3, delay = 3000)
@Path("/{id}")
public Response getTvSeriesById(@PathParam("id") int id) {
System.out.println("Trying to access TV Series with id ::::::::: "+id);
return Response.ok(tvSeriesProxy.getTvSeriesById(id)).build();
}
public Response fallback(int id) {
return Response.ok("Site is under maintainance").build() ;
}
Retry Mechanism
Circuit Breaker
@GET
@Fallback(
fallbackMethod = "fallback",
applyOn = {RuntimeException.class} ,
skipOn = {IllegalArgumentException.class}
)
@CircuitBreaker( requestVolumeThreshold = 4, failureRatio = 0.75, delay = 5000)
@Path("/{id}")
public Response getTvSeriesById(@PathParam("id") int id) {
System.out.println("Trying to access TV Series with id ::::::::: "+id);
return Response.ok(tvSeriesProxy.getTvSeriesById(id)).build();
}
public Response fallback(int id) {
return Response.ok("Site is under maintainance").build() ;
}while true; do sleep 1;curl http://localhost:8080/tvseries/169; echo -e '\n';doneDependency Injection
package org.acme;
import jakarta.annotation.PostConstruct;
import jakarta.inject.Singleton;
@Singleton
public class MyGreeting {
@PostConstruct
void init() {
System.out.println("MyGreeting bean created");
}
public String greet() {
return "This is greeting from a bean";
}
}
package org.acme;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
@Path("/hello")
public class GreetingResource {
@Inject
MyGreeting myGreeting;
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return myGreeting.greet();
}
}
Hibernate with QUARKUS

application.properties
quarkus.datasource.db-kind=mysql
quarkus.datasource.jdbc.url=jdbc:mysql://localhost:3306/mydb
quarkus.datasource.username=root
quarkus.datasource.password=
quarkus.hibernate-orm.database.generation=update
quarkus.hibernate-orm.log.sql=truepackage org.quarkus.hibernate.demo;
import jakarta.persistence.*;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long id;
public String name;
public String email;
}package org.quarkus.hibernate.demo;
import io.quarkus.hibernate.orm.panache.PanacheRepository;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class UserRepository implements PanacheRepository<User> {
public User findByEmail(String email) {
return find("email", email).firstResult();
}
}
package org.quarkus.hibernate.demo;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
import java.util.List;
@Path("/users")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class UserResource {
@Inject
UserRepository userRepository;
@GET
public List<User> getAllUsers() {
return userRepository.listAll();
}
@POST
@Transactional
public void addUser(User user) {
userRepository.persist(user);
}
}
curl -X POST http://localhost:8080/users -H "Content-Type: application/json" -d '{"name": "Alice", "email": "alice@example.com"}'
curl -X GET http://localhost:8080/users
quarkus
By Pulkit Pushkarna
quarkus
- 20