Skip to content

Latest commit

 

History

History
181 lines (138 loc) · 4.99 KB

File metadata and controls

181 lines (138 loc) · 4.99 KB

Limitly — Complete Documentation & Setup Guide

Limitly is a production-grade, zero-config Spring Boot starter library for Redis-backed rate limiting. It guarantees atomic execution across distributed microservice pod replicas using Lua scripting.


📦 How to Add as a Maven Dependency

Option 1: Local Maven Repository (mvn install)

If you are building and consuming Limitly locally across projects on your machine:

  1. Clone and install Limitly into your local ~/.m2/repository:

    git clone https://github.com/onizukaTP/limitly.git
    cd limitly
    mvn clean install
  2. Add the dependency to your application's pom.xml:

    <dependency>
        <groupId>io.github.tharunprabu</groupId>
        <artifactId>redis-rate-limiter-spring-boot-starter</artifactId>
        <version>0.1.0-SNAPSHOT</version>
    </dependency>

Option 2: Via JitPack (Instant GitHub Dependency without Maven Central deployment)

You can consume Limitly directly from GitHub releases or branches using JitPack:

  1. Add the JitPack repository to your application's pom.xml:

    <repositories>
        <repository>
            <id>jitpack.io</id>
            <url>https://jitpack.io</url>
        </repository>
    </repositories>
  2. Add the Limitly dependency:

    <dependency>
        <groupId>com.github.onizukaTP</groupId>
        <artifactId>limitly</artifactId>
        <version>master-SNAPSHOT</version>
    </dependency>

Option 3: Maven Central (When Released)

<dependency>
    <groupId>io.github.tharunprabu</groupId>
    <artifactId>redis-rate-limiter-spring-boot-starter</artifactId>
    <version>0.1.0</version>
</dependency>

🛠️ Complete Configuration Reference

Add these properties to your application.yml:

spring:
  data:
    redis:
      host: localhost
      port: 6379

rate-limiter:
  # Master toggle to enable/disable rate limiting
  enabled: true
  
  # Default algorithm strategy across endpoints if unspecified: SLIDING_WINDOW | TOKEN_BUCKET
  default-strategy: SLIDING_WINDOW
  
  # Default key resolver: USER | IP | SPEL
  default-key-resolver: USER
  
  # Behavior when Redis is down/unreachable: FAIL_OPEN | FAIL_CLOSED
  fallback-mode: FAIL_OPEN
  
  redis:
    # Prefix for all Redis keys created by Limitly
    key-prefix: "ratelimit:"
    
  response:
    # HTTP status returned when rate limit is breached (default: 429)
    status: 429
    # JSON body returned to throttled clients
    body: '{"error": "rate_limit_exceeded", "message": "Too many requests. Please try again later."}'
    # Whether to return the standard 'Retry-After' header (seconds remaining)
    include-retry-after-header: true
    
  metrics:
    # Enable Micrometer metrics collection
    enabled: true

💡 @RateLimit Annotation Usage & Examples

1. Sliding Window Log (Exact Accuracy)

Ideal for security-sensitive endpoints (logins, payment APIs, password resets).

@GetMapping("/api/login")
@RateLimit(limit = 5, window = "1m", strategy = Algorithm.SLIDING_WINDOW)
public ResponseEntity<?> login() {
    return ResponseEntity.ok("Logged in");
}

2. Token Bucket Algorithm (Allows Micro-Bursts)

Ideal for standard REST APIs, data ingestion, and file downloads.

@GetMapping("/api/posts")
@RateLimit(limit = 100, window = "1m", strategy = Algorithm.TOKEN_BUCKET)
public ResponseEntity<?> getPosts() {
    return ResponseEntity.ok(postService.findAll());
}

3. Dynamic Key Resolution with SpEL

Resolve rate limits per IP, user ID, or request attributes using Spring Expression Language:

// Rate limit by client remote IP address
@PostMapping("/api/comments")
@RateLimit(key = "#request.remoteAddr", limit = 10, window = "30s")
public ResponseEntity<?> postComment(HttpServletRequest request) {
    return ResponseEntity.ok("Comment posted");
}

4. Critical Endpoint with FAIL_CLOSED Protection

If Redis goes down, FAIL_CLOSED denies traffic to protect sensitive backend systems.

@PostMapping("/api/payment/checkout")
@RateLimit(limit = 3, window = "10s", onRedisFailure = FallbackMode.FAIL_CLOSED)
public ResponseEntity<?> checkout() {
    return ResponseEntity.ok("Payment processed");
}

📈 Monitoring & Actuator Metrics

Limitly integrates out-of-the-box with Micrometer, Prometheus, and Spring Boot Actuator.

Metric Name Type Description
ratelimiter.requests.allowed Counter Total requests that passed rate limits
ratelimiter.requests.denied Counter Total requests throttled (429)
ratelimiter.redis.latency Timer Execution duration of Redis Lua scripts
ratelimiter.redis.failures Counter Count of Redis connectivity fallback events

🧪 Window Time String Formats

The window attribute in @RateLimit supports standard shorthand duration strings:

  • "500ms" (500 milliseconds)
  • "10s" (10 seconds)
  • "5m" (5 minutes)
  • "1h" (1 hour)
  • "1d" (1 day)
  • Standard ISO-8601 strings (e.g. "PT1M")