RL
GitHub
Documentation

Integrate in 5 Minutes

Quickstart for adding distributed rate limiting to Spring Boot.

Integrate in 5 Minutes

Add distributed rate limiting to a Spring Boot service with Redis state and optional MongoDB overrides.

What this gives you

You get four algorithms (Token Bucket, Leaky Bucket, Fixed Counter, Sliding Window), per-IP + per-endpoint + per-tier configuration, atomic Redis state via Lua, and optional persistent overrides stored in MongoDB.

Request flow

Request flow

The filter intercepts each request, resolves configuration from MongoDB and YAML, executes the chosen Redis Lua script, and returns a decision with headers.

Prerequisites

  • Java 21
  • Spring Boot 4.x
  • Redis (local or managed)
  • MongoDB (optional but recommended for runtime overrides)

If you already have a Spring Boot service, you keep it and add the rate limiter module.

1) Run dependencies

Start Redis and MongoDB locally.

bash
# Redis
redis-server

# MongoDB (default)
mongod

If you use containers instead, just keep the connection strings for the next step.

2) Configure application.yaml

Add the rate-limit section and your Redis/Mongo settings. This example uses a Token Bucket fallback and a per-endpoint config with user tiers.

yaml
spring:
  data:
    mongodb:
      uri: mongodb://admin:password@localhost:27017/rate_limiter_db
      authentication-database: admin

  redis:
    host: localhost
    port: 6379

rate-limit:
  fallback:
    algorithm: TOKEN_BUCKET
    capacity: 3
    refillRate: 1

  endpoints:
    - path: /api/test
      user-tiers:
        free:
          algorithm: TOKEN_BUCKET
          capacity: 5
          refillRate: 0
        premium:
          algorithm: LEAKY_BUCKET
          capacity: 5
          flowRate: 1

  redis:
    key-prefix: "rate-limit"
    ttl: 600000

  security:
    enabled: true
    trusted-proxies:
      - 127.0.0.1
      - 10.0.0.0/8
      - 172.16.0.0/12
      - 192.168.0.0/16

The fallback block defines the default algorithm when no endpoint match exists. The endpoints list defines per-path rules. Each tier under user-tiers can pick a different algorithm and parameters. The Redis TTL determines how long a key survives without traffic; keep it long enough to avoid churn but short enough to avoid stale keys.

If you misconfigure the algorithm parameters, the service returns 400 Bad Request from the config endpoints or logs a validation error during startup. Fix the values and restart.

3) Run the service

bash
./mvnw spring-boot:run

4) Hit a rate-limited endpoint

bash
curl -i http://localhost:8080/api/test

You should see these headers in the response:

http
X-RateLimit-Limit: 5
X-RateLimit-Remaining: 4
X-RateLimit-ResetOn: 1713005400000

X-RateLimit-ResetOn is a Unix timestamp in milliseconds. When X-RateLimit-Remaining reaches 0, the next request returns 429 Too Many Requests until that time.

5) Add a persistent override (optional)

Store a per-IP + endpoint + tier override in MongoDB.

bash
curl -X POST http://localhost:8080/api/config/v2 \
  -H "Content-Type: application/json" \
  -d '{
    "ip": "192.168.1.100",
    "endpoint": "/api/test",
    "userTier": "premium",
    "method": "GET",
    "algorithm": "TOKEN_BUCKET",
    "parameters": {
      "capacity": 100,
      "refillRate": 10
    }
  }'

This override has the highest priority. The next request from that IP to that endpoint uses the MongoDB config instead of the YAML defaults. If the IP or endpoint does not match, the YAML configuration still applies.

If you send an invalid payload, the service returns 400 Bad Request. Validate the algorithm name and required fields, then retry. If MongoDB is down, you will get a 503 and no override is stored.

What to verify

Confirm that:

  • X-RateLimit-* headers appear on rate-limited endpoints.
  • 429 Too Many Requests appears once you exceed the limit.
  • A MongoDB override changes behavior for the matching IP + endpoint + tier.

Request processing flow

mermaid
flowchart LR
  A[HTTP Request] --> B[RateFilter]
  B --> C[RateLimitManager]
  C --> D{Config Resolution}
  D -->|MongoDB| E[Mongo Config]
  D -->|YAML| F[YAML Config]
  D -->|Fallback| G[Fallback]
  C --> H[Redis Lua Script]
  H --> I[Decision + Headers]