Rate limiting per user or API key (e.g., 100 requests/min).
Time-based quota tracking (fixed window/sliding window/token bucket).
Real-time enforcement of limits (must reject/allow immediately).
Custom rules (different limits for different endpoints or users).
Distributed support (should work across multiple servers).
Auditing & Logging of throttled requests.
Admin interface to update limits.
High availability – must not be a single point of failure.
Low latency – check must complete in a few milliseconds.
Scalability – must support millions of requests per second.
Consistency – decision should be consistent across nodes.
Fault tolerance – should gracefully degrade or retry on failure.
Assume:
The rate-limiter must sustain 2M QPS at peak traffic.
POST /check_rate_limit
Payload: { "user_id": "123", "api_key": "abc", "endpoint": "/upload" }
Response: { "allowed": true/false, "remaining_quota": int }
POST /update_limit
Payload: { "user_id": "123", "limit": 100, "duration_sec": 60 }
GET /limits
GET /metrics
Fast in-memory counters.
TTLs for automatic expiration.
Atomic operations (via Lua scripts or INCR + EXPIRE).
Schema (Redis Keys):
rate:{user_id}:{endpoint} => counter + TTL
rate-limit-config:{user_id} => {limit: 100, duration: 60}
Components:
Client → API Gateway → Rate Limiter → Redis → Decision (Allow/Deny)
API Gateway receives request.
Gateway calls RateLimiterService.check(user_id, endpoint).
Service uses INCR and EXPIRE in Redis to count and enforce limits.
If over limit, return HTTP 429 (Too Many Requests).
If under limit, pass to downstream API.
Log rate limit usage for audit and metrics.
INCR for atomic counters.EXPIRE).| Redis for counters | Atomic ops, TTL support, fast | Memory-intensive; must handle partitioning |
| Centralized rate limiter | Easier to manage, consistent rules | May become bottleneck – mitigated by sharding |
| Fixed window algorithm | Simpler, efficient | Burstiness allowed at edges |
| Token bucket (optional) | Smoothens traffic | More complex to implement |
| Lua scripts in Redis | Atomic + fast execution | Harder to debug, adds complexity |
| API Gateway check | Low latency | Extra hop per request |
Implement sliding window log or leaky bucket for smoother control.
Use local caching + syncing to reduce Redis dependency.
Add user-specific or endpoint-specific dynamic rate limits.
Expose GraphQL UI or Admin Panel for real-time updates.
Integrate AI anomaly detection on rate-limiting patterns.