<500 Microseconds Overhead
1 Annotation to Protect
0 Config Required
100% Open Source
Redis Ready for Scale
<500 Microseconds Overhead
1 Annotation to Protect
0 Config Required
100% Open Source
Redis Ready for Scale

Built for Real Production

Designed with production patterns in mind. Clean architecture. Extensible by design.

Blazing Fast

Sub-millisecond decisions won't slow your hot paths. O(1) algorithms, lock-free data structures, and zero allocations in the critical path.

One Line Setup

Add @RateLimit and you're done. No XML configs, no boilerplate, no ceremony. Works instantly with Spring Boot and Quarkus.

Scales Horizontally

Redis backend with atomic Lua scripts ensures consistent limits across your entire cluster. No double-counting, no race conditions.

Fails Gracefully

Redis down? Circuit breakers kick in. Tiered L1/L2 storage keeps your app running. Designed for the chaos of production.

Security First

SpEL injection attacks? Blocked. Key enumeration? Prevented. PII in logs? Masked. We sweat the security details so you don't have to.

Full Visibility

Prometheus metrics out of the box. Know exactly who's hitting limits, what's being blocked, and when to adjust your quotas.

<0μs
Per-Request Overhead
0M+
Requests/sec Tested
0
Dependencies (Core)
0%
Test Coverage

Use Only What You Need

Modular by design. Small JARs. No bloat. Mix and match for your stack.

Module What It Does Size
rl-core The engine: algorithms, resilience, security. Zero dependencies. ~10.8K LOC
rl-spi-redis Distributed storage. Atomic Lua scripts. Cluster-ready. ~770 LOC
rl-spi-caffeine In-memory storage. Blazing fast. Great for single-instance. ~800 LOC
rl-adapter-spring Drop-in for Spring Boot. Auto-config. AOP magic included. ~2.7K LOC
rl-adapter-quarkus Native Quarkus support. CDI interceptors. GraalVM ready. ~800 LOC

Two Steps. That's It.

Add the dependency. Add the annotation. Your API is protected.

1. Add Dependency (pom.xml)
<dependency>
    <groupId>com.lycosoft</groupId>
    <artifactId>rl-adapter-spring</artifactId>
    <version>0.1.0-beta.1</version>
</dependency>
2. Use the Annotation
@RestController
public class OrderController {

    // Allow 100 requests per 60 seconds
    @RateLimit(requests = 100, window = 60)
    @GetMapping("/orders")
    public List<Order> getOrders() {
        return orderService.findAll();
    }
}
1. Add Dependency (pom.xml)
<dependency>
    <groupId>com.lycosoft</groupId>
    <artifactId>rl-adapter-quarkus</artifactId>
    <version>0.1.0-beta.1</version>
</dependency>
2. Use the Annotation
@Path("/orders")
public class OrderResource {

    // Allow 100 requests per 60 seconds
    @RateLimit(requests = 100, window = 60)
    @GET
    public List<Order> getOrders() {
        return orderService.findAll();
    }
}

Beyond the Basics

Powerful enough for complex scenarios. Simple enough to understand.

Limit by User

Use SpEL expressions to rate limit per authenticated user.

@RateLimit(
    key = "#user.id",
    requests = 100,
    window = 60
)
@PostMapping("/api/orders")
public Order createOrder(
    @AuthenticationPrincipal User user,
    @RequestBody OrderRequest request
) {
    return orderService.create(request);
}

Multi-Tenant Apps

Combine tenant + user for SaaS-style fair usage limits.

@RateLimit(
    key = "#tenant.id + ':' + #user.id",
    requests = 50,
    window = 60
)
public void tenantAction() { ... }

Burst Protection + Quotas

Stack multiple limits: prevent sudden spikes AND enforce long-term quotas.

@RateLimits({
    @RateLimit(name = "burst", requests = 10, window = 1),       // 10 req/sec max
    @RateLimit(name = "hourly", requests = 1000, window = 3600)  // 1000 req/hour quota
})
@GetMapping("/api/resource")
public Resource getResource() {
    return resourceService.fetch();
}

Optional Tuning

Works out of the box. Fine-tune when you need to.

ratelimit:
  enabled: true
  storage: redis          # or: caffeine
  spel:
    compiler-mode: IMMEDIATE
    cache-size: 1000

Built-in Metrics

Prometheus-ready. Alert on abuse before it becomes a problem.

# Who's getting blocked?
rate(ratelimit_denied_total[5m])

# How much traffic is allowed?
sum(rate(ratelimit_allowed_total[5m]))

Comprehensive Guides

Everything you need to implement rate limiting in your application.

Developer Guide

Complete reference for all features, algorithms, and YAML configuration options.

Read Guide

Spring Boot Guide

Annotation-driven rate limiting with auto-configuration for Spring Boot applications.

Read Guide

Quarkus Guide

CDI interceptors with reactive support and native compilation compatibility.

Read Guide

Standalone Guide

Use the core library directly in any Java application without frameworks.

Read Guide

Ready to Protect Your APIs?

Join developers who ship faster without worrying about abuse.