Software Development

Understanding Load Shedding with Quarkus

Load shedding is a crucial resilience mechanism in distributed systems that prevents system overload by rejecting excessive traffic during high-demand periods. In microservices architectures, this becomes particularly important to maintain performance and stability. Quarkus, a Kubernetes-native Java framework tailored for GraalVM and OpenJDK HotSpot, provides a reactive foundation that can be extended for load shedding. Let us delve into understanding quarkus load shedding.

1. What is Quarkus?

Quarkus is a modern, Kubernetes-native Java framework tailored for building high-performance microservices and serverless applications. It is specially designed for cloud and container-first environments, such as Kubernetes and OpenShift. Quarkus optimizes Java specifically for GraalVM and HotSpot, enabling extremely fast boot times and significantly reduced memory usage.

It embraces both traditional imperative programming paradigms and modern reactive programming models, making it a versatile choice for a wide range of application architectures. Developers can leverage popular Java standards like JAX-RS (RESTEasy), CDI, JPA, and also benefit from asynchronous and event-driven development using Vert.x.

1.1 Key Features

  • Fast Startup and Low Memory Usage: Quarkus applications start up in milliseconds and consume significantly less RAM compared to traditional Java applications, making them ideal for microservices and serverless environments.
  • Imperative and Reactive Programming: Quarkus supports both imperative development using standard APIs (like JAX-RS and CDI) and reactive development using libraries such as Vert.x and Mutiny.
  • GraalVM Native Compilation: Integration with GraalVM Native Image allows developers to compile their applications ahead-of-time (AOT) into native executables, improving performance and reducing resource consumption.
  • Developer Joy: Features like Dev UI, live reload, unified configuration, and streamlined testing improve developer productivity and speed up the feedback loop.
  • Extensive Extension Ecosystem: Quarkus provides hundreds of extensions out-of-the-box to support commonly used technologies such as Hibernate ORM, Apache Kafka, RESTEasy, and Panache.
  • Cloud-Native & Kubernetes Ready: Quarkus generates Kubernetes resources automatically and supports container image builds via tools like Jib, Docker, or S2I.

1.2 Use Cases

  • Building lightweight microservices that scale efficiently in the cloud:
  • Creating serverless functions with fast cold start performance
  • Modernizing monolithic Java applications for container-based deployments
  • Developing event-driven systems and reactive APIs
  • Implementing edge and IoT solutions with limited system resources

1.3 Quarkus Load Shedding Extension

Although Quarkus does not offer native load-shedding capabilities akin to Netflix Hystrix, the ecosystem has evolved to support third-party and community-driven extensions for graceful degradation. One such emerging tool is the Quarkus Load Shedding Extension, which provides structured, configurable mechanisms to shed load during traffic spikes or system distress proactively. This extension integrates closely with Quarkus’s reactive model and leverages Vert.x event loops to enforce backpressure.

The Quarkus Load Shedding Extension is designed to:

  • Proactively reject excessive traffic based on runtime metrics.
  • Plug into Vert.x’s reactive core to monitor event loop saturation.
  • Support configuration via application properties.
  • Return appropriate HTTP status codes like 429 Too Many Requests when shedding occurs.
  • Work seamlessly with Quarkus filters, interceptors, and CDI contexts.

1.3.1 Benefits of Using the Extension

  • Declarative Configuration: Easily fine-tune load-shedding behavior via application properties.
  • Non-Invasive Integration: No need to manually add semaphores or custom logic in each method.
  • Reactive Friendly: Built for Quarkus’s reactive runtime and Vert.x event model.
  • Fail-Fast Philosophy: Drops low-priority requests early to preserve availability for critical paths.

1.3.2 When to Use

  • In APIs exposed to external clients with bursty or unpredictable usage.
  • In services where you need to protect downstream systems or maintain latency SLAs.
  • In reactive systems that must prevent event loop starvation.

2. Project Setup and Adding Dependencies (pom.xml)

To get started with Quarkus, you can use the Quarkus code generator or set up manually using Maven:

mvn io.quarkus.platform:quarkus-maven-plugin:3.9.2:create \
  -DprojectGroupId=com.loadshedding \
  -DprojectArtifactId=load-shedding-demo \
  -DclassName="com.loadshedding.api.GreetingResource" \
  -Dpath="/hello"

Navigate to the project (cd load-shedding-demo) and add the following dependencies in pom.xml for REST and metrics support:

<dependency>
    <groupId>io.quarkiverse.loadshedding</groupId>
    <artifactId>quarkus-load-shedding</artifactId>
    <version>latest__jar__version</version>
</dependency>

Then, in your application.properties, configure shedding thresholds:

# Enable load shedding
quarkus.load-shedding.enabled=true

# Max number of concurrent requests allowed
quarkus.load-shedding.max-concurrent-requests=100

# Vert.x event loop max latency in ms (above this, load is shed)
quarkus.load-shedding.event-loop-latency-threshold=200

# HTTP status code to return on load shed
quarkus.load-shedding.response-status=429

3. How It Works

Under the hood, the extension hooks into the request pipeline and evaluates two primary factors:

  • Request Concurrency: If the number of active in-flight requests exceeds a configurable limit (max-concurrent-requests), the request is rejected.
  • Event Loop Latency: If Vert.x detects that event loop delays exceed the defined threshold, it triggers shedding to preserve system responsiveness.

3.1 Code Example: Annotated Resource

The extension allows you to annotate specific endpoints to opt-in to shedding behavior:

package com.loadshedding.api;

import io.quarkiverse.loadshedding.LoadShed;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.core.Response;

@Path("/shed")
public class LoadSheddingExtensionResource {

    @GET
    @LoadShed
    public Response getShed() {
        return Response.ok("Request accepted under threshold").build();
    }
}

3.1.1 Code Explanation and Output

This Java code defines a REST endpoint using Quarkus and Jakarta REST, which is protected by a load-shedding mechanism. The class is mapped to the path /shed, and the getShed method handles HTTP GET requests. The @LoadShed annotation from the Quarkiverse Load Shedding extension is used to automatically reject requests when system thresholds (like CPU, memory, or concurrency limits) are exceeded. If the system is operating within acceptable limits, the endpoint returns a 200 OK response with the message “Request accepted under threshold”.

Upon exceeding the request limit, the response will look like this:

HTTP/1.1 429 Too Many Requests
Content-Type: text/plain

Service temporarily unavailable due to a high load

Please note, since this is a community or early-stage extension, always review the extension’s stability and compatibility with your target Quarkus version before use in production.

3.2 Default Load Shedding

In default load shedding, the Quarkiverse Load Shedding extension applies out-of-the-box strategies to reject excess requests when the system is under stress. This includes limiting concurrent requests and monitoring event loop latency. Developers can enable it declaratively using the @LoadShed annotation and configure it via application.properties.

-- application.properties
quarkus.load-shed.max-concurrent-requests=100
quarkus.load-shed.event-loop.max-delay=500ms

-- Code snippet
import io.quarkiverse.loadshedding.LoadShed;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.core.Response;

@Path("/api")
public class DefaultSheddingResource {

    @GET
    @LoadShed
    public Response getData() {
        return Response.ok("Request served").build();
    }
}

With this setup, requests are automatically rejected with 429 Too Many Requests if concurrency or latency thresholds are breached.

3.3 Custom Load Shedding

Custom load shedding enables developers to define their own request rejection logic by implementing the LoadShedDecider interface. This is useful for applying advanced heuristics such as checking custom metrics, downstream service availability, or user-specific limits.

import io.quarkiverse.loadshedding.spi.LoadShedDecider;
import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class CustomSheddingDecider implements LoadShedDecider {

    @Override
    public boolean shouldDropRequest() {
        // Custom logic: for example, shed requests if memory is low or DB is slow
        boolean isSystemUnderPressure = checkCustomMetrics();
        return isSystemUnderPressure;
    }

    private boolean checkCustomMetrics() {
        // Example stub logic
        return Runtime.getRuntime().freeMemory() < 100 * 1024 * 1024;
    }
}

This approach gives fine-grained control over the load shedding policy while maintaining Quarkus integration.

4. Conclusion

Load shedding is vital for ensuring the resilience of high-throughput applications. While Quarkus doesn’t provide load shedding out of the box like Hystrix, it offers enough flexibility to implement both simple and advanced custom strategies using Java constructs, CDI interceptors, and Vert.x reactive capabilities. Whether using semaphores to limit concurrency or system metrics to conditionally reject requests, Quarkus allows you to build scalable and fault-tolerant services suited for modern cloud environments.

Yatin Batra

An experience full-stack engineer well versed with Core Java, Spring/Springboot, MVC, Security, AOP, Frontend (Angular & React), and cloud technologies (such as AWS, GCP, Jenkins, Docker, K8).
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button