Limitly is a production-grade, zero-config Spring Boot starter library for Redis-backed rate limiting. It provides annotation-driven request throttling with atomic Lua execution on Redis.
Configure Redis host details and rate limiter defaults in your Spring Boot application's application.yml:
spring:
data:
redis:
host: localhost
port: 6379
rate-limiter:
enabled: true
default-strategy: SLIDING_WINDOW # Options: SLIDING_WINDOW | TOKEN_BUCKET
default-key-resolver: USER # Options: USER | IP | SPEL
fallback-mode: FAIL_OPEN # Options: FAIL_OPEN | FAIL_CLOSED
redis:
key-prefix: "ratelimit:"
response:
status: 429
body: '{"error": "rate_limit_exceeded", "message": "Too many requests. Please try again later."}'
include-retry-after-header: true
metrics:
enabled: trueDrop the @RateLimit annotation directly on your REST endpoints:
Restricts users to 5 requests per 10 seconds using a Redis Sorted Set (ZSET).
@RestController
@RequestMapping("/api")
public class ProductController {
@GetMapping("/products/search")
@RateLimit(limit = 5, window = "10s", strategy = Algorithm.SLIDING_WINDOW)
public ResponseEntity<?> search(@RequestParam String query) {
return ResponseEntity.ok(Map.of("query", query));
}
}Refills continuous tokens per second using a Redis Hash (HMSET).
@PostMapping("/api/ads")
@RateLimit(limit = 10, window = "1m", strategy = Algorithm.TOKEN_BUCKET)
public ResponseEntity<?> createAd() {
return ResponseEntity.ok("Ad created");
}Throttles based on client remote IP, custom headers, or session attributes using Spring Expression Language:
@PostMapping("/api/comments")
@RateLimit(key = "#request.remoteAddr", limit = 3, window = "30s")
public ResponseEntity<?> postComment(HttpServletRequest request) {
return ResponseEntity.ok("Comment posted");
}If Redis crashes or suffers network issues, FAIL_CLOSED will block traffic to preserve critical databases.
@PostMapping("/api/checkout")
@RateLimit(limit = 2, window = "5s", onRedisFailure = FallbackMode.FAIL_CLOSED)
public ResponseEntity<?> checkout() {
return ResponseEntity.ok("Payment processed");
}You can specify duration shorthand strings in the window attribute:
"500ms"→ 500 milliseconds"10s"→ 10 seconds"5m"→ 5 minutes"1h"→ 1 hour"1d"→ 1 day- ISO-8601 strings e.g.
"PT1M"
Limitly automatically registers Micrometer metrics when micrometer-core and Spring Boot Actuator are present:
| Metric Name | Type | Description |
|---|---|---|
ratelimiter.requests.allowed |
Counter | Total requests allowed through |
ratelimiter.requests.denied |
Counter | Total requests throttled (HTTP 429) |
ratelimiter.redis.latency |
Timer | Execution duration of Redis Lua scripts |
ratelimiter.redis.failures |
Counter | Count of Redis outage fallback triggers |