Skip to content

s8sankalp/RateLimiter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 

Repository files navigation

RateLimiter — Spring Boot + Redis Token Bucket

A basic HTTP Rate Limiter built with Spring Boot and Redis. Implements the Token Bucket algorithm to control request rates per client, returning HTTP 429 Too Many Requests when limits are exceeded.

Architecture

HTTP Request
    │
    ▼
┌─────────────────────────────┐
│     RateLimiterFilter       │  ← OncePerRequestFilter (runs on every request)
│  • Resolves client identity │
│  • Calls isAllowed()        │
└───────────┬─────────────────┘
            │ allowed?
     ┌──────┴────────┐
     │ YES           │ NO
     ▼               ▼
  Forward         HTTP 429
  Request      (ErrorResponse)
     │
     ▼
┌──────────────────────────────┐
│  RedisTokenBucketService     │
│  • refillTokens()            │  ← Calculates elapsed time, adds tokens
│  • isAllowed()               │  ← Atomically checks & decrements token
│  • getTokenCount()           │  ← Read-only inspection
└──────────────┬───────────────┘
               │
               ▼
          Redis (Jedis)
    rate_limiter:tokens:<clientId>
    rate_limiter:last_refill:<clientId>

Token Bucket Algorithm

Parameter Default Description
capacity 10 Max tokens per client (burst size)
refillRate 5 Tokens added per second

How it works:

  1. Each client gets a virtual bucket of tokens (max = capacity)
  2. Every accepted request consumes 1 token
  3. Tokens refill at refillRate per second up to capacity
  4. When the bucket is empty → HTTP 429 Too Many Requests
  5. On Redis failure → fail-open (requests are allowed)

Client Identity Resolution

The filter resolves client identity in priority order:

  1. X-Client-Id request header (explicit client ID)
  2. X-Forwarded-For header (set by load balancers/proxies)
  3. TCP remote IP address (direct connections)

Prerequisites

  • Java 17+
  • Maven 3.8+
  • Docker & Docker Compose (for Redis)

Quick Start

1. Start Redis

cd RateLimiter-sb
docker-compose up -d

2. Run the Application

./mvnw spring-boot:run

The server starts on http://localhost:8080

Configuration

Edit src/main/resources/application.properties:

# Token Bucket configuration
rate-limiter.capacity=10       # Burst size (max tokens)
rate-limiter.refill-rate=5     # Tokens added per second

# Redis connection
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.timeout=2000

API Reference

Rate Limit Status

GET /api/rate-limit/status?clientId={clientId}

Returns current token state for a client without consuming a token.

Response (200 OK):

{
  "clientId": "127.0.0.1",
  "tokensRemaining": 8,
  "capacity": 10,
  "refillRatePerSecond": 5,
  "allowed": true,
  "message": "Requests are currently permitted."
}

Health Check

GET /actuator/health

Rate Limit Exceeded Response

When a client exceeds their limit, all requests receive:

Response (429 Too Many Requests):

{
  "timestamp": "2026-04-19T10:00:00Z",
  "status": 429,
  "error": "Too Many Requests",
  "message": "Rate limit exceeded. Please slow down and try again later.",
  "clientId": "127.0.0.1"
}

Testing with curl

# Fire 10 requests — all should succeed (HTTP 200)
for i in {1..10}; do
  curl -s -o /dev/null -w "Request $i: %{http_code}\n" \
    -H "X-Client-Id: test-user" \
    http://localhost:8080/api/rate-limit/status
done

# 11th request — should return 429
curl -v -H "X-Client-Id: test-user" http://localhost:8080/api/rate-limit/status

# Check token count without consuming
curl http://localhost:8080/api/rate-limit/status?clientId=test-user

Running Tests

./mvnw test

Project Structure

src/main/java/com/RateLimiter/RateLimiter_sb/
├── RateLimiterSbApplication.java       # Spring Boot entry point
├── config/
│   ├── RateLimiterProperties.java      # Rate limit config binding
│   ├── RedisProperties.java            # Jedis pool factory
│   └── SecurityConfig.java            # Disables default HTTP Basic auth
├── dto/
│   ├── RateLimitStatusResponse.java    # Status endpoint response
│   └── ErrorResponse.java             # 429 error response body
├── filter/
│   └── RateLimiterFilter.java         # OncePerRequestFilter — enforcement
├── controller/
│   └── RateLimiterController.java     # /api/rate-limit/status endpoint
└── services/
    └── RedisTokenBucketService.java   # Token bucket logic (Redis-backed)

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages