Rate-Limiting Algorithms and Atomic Shared Counters
A fixed window is simple but permits bursts around window boundaries. Sliding-window logs are precise but consume more state; sliding-window counters approximate a rolling rate. Token bucket allows controlled bursts up to capacity while replenishing tokens at a configured rate. Leaky bucket smooths output.
Distributed limits require shared state or equivalent coordination; per-instance counters can be bypassed by routing requests across replicas. Redis scripts or atomic operations can check and update a token bucket without race conditions. Keys should include the correct scope—tenant, user, API key, endpoint—and expire to prevent unbounded growth.
Rate limits and concurrency limits solve different problems. A tenant can stay under a request-per-minute quota while occupying all workers with slow requests. Combine quotas, in-flight concurrency, and fair scheduling for expensive workloads. Decide whether limiter-store failure should fail open or fail closed based on risk.
Simple, but boundary bursts possibleMore accurate rolling rate, more stateAverage rate plus controlled burstsSmooths output toward a configured rate