Design Exercise: Distributed Rate Limiter
Requirements
- Limit API requests per user/IP
- Distributed (works across multiple app servers)
- Low latency (< 1ms overhead per request)
- Configurable rules (100 req/min for free tier, 1000 for paid)
Architecture
Client ──► API Gateway ──► Rate Limiter Middleware ──► App Server
│
▼
Redis Cluster
(shared counters/tokens)
Implementation: Sliding Window + Redis
// Redis sorted set: store request timestamps
ZADD rate:{user_id} {timestamp} {request_id}
ZREMRANGEBYSCORE rate:{user_id} 0 {timestamp - window}
ZCARD rate:{user_id} → count in current window
// If count > limit → reject with 429
// All in one Lua script for atomicity
Response Headers
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1709001234
Retry-After: 30
Rules Engine
// Different limits per tier/endpoint:
rules:
- match: {tier: "free", endpoint: "/api/*"}
limit: 100/minute
- match: {tier: "pro", endpoint: "/api/*"}
limit: 1000/minute
- match: {endpoint: "/api/expensive"}
limit: 10/minute