Rate Limiting
A strategy for limiting network traffic to prevent users from exhausting system resources or performing brute-force attacks.
Detailed Explanation
Rate limiting (e.g., '100 requests per minute per IP') protects your API from being overwhelmed by traffic spikes (DDoS) and stops attackers from trying thousands of password combinations in seconds. It is a critical layer of defense for any public-facing API or authentication endpoint.
Quick Summary
Rate limiting caps how many requests a client can make in a time window, protecting backends from overload, abuse, and brute-force attempts. It's one of the cheapest controls with the biggest impact.
Key Takeaways
- Common algorithms: fixed window (simple, edge effects), sliding window, token bucket (allows bursts), leaky bucket (smooths).
- Identify clients by API key, user ID, or IP, IP-only is weakest because of NAT and proxies.
- Return 429 Too Many Requests with a Retry-After header so well-behaved clients back off correctly.
- Layer it: at the edge (CDN/WAF), at the API gateway, and inside the app for sensitive endpoints.
- Per-endpoint limits matter, login and search need much tighter rates than read-only public endpoints.
When to use it
- Login and password-reset endpoints to slow brute-force credential attacks.
- Public APIs to enforce per-tier quotas on free vs. paid plans.
- Webhook receivers to prevent a noisy sender from drowning out others.
- Expensive endpoints (search, export, AI calls) where per-request cost is significant.
Common Mistakes
- Storing rate-limit counters in app memory; behind multiple instances each one allows the full quota.
- IP-only limits behind a CDN or load balancer, so all users from one egress IP share one bucket.
- Returning generic 503 or 500 instead of 429, so clients can't tell apart "slow down" from "broken."
- Identical limits across endpoints, login should be far stricter than `/healthz`.
Rate Limiting, Frequently Asked
Where should I implement rate limiting?
Edge/CDN for crude abuse protection (volume), API gateway for per-key business limits, and application code for per-user/per-endpoint logic. Cheap controls at the edge save the expensive ones for nuanced rules.
Token bucket vs. leaky bucket?
Token bucket allows bursts up to capacity, then sustains at refill rate, good for user-facing APIs. Leaky bucket smooths to a constant rate, blocking bursts, good for protecting downstream systems that can't handle spikes.
How do I share rate-limit state across instances?
Use a shared store, Redis is the standard for fast atomic counters. Cloud services (Cloudflare, AWS WAF, API Gateway) provide rate limiting as a managed feature so you don't have to run the counter store yourself.