Design Exercise: Distributed Rate Limiter

Requirements

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