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.

Rate limiter comparison
Fixed window: Simple, but boundary bursts possible
Sliding window: More accurate rolling rate, more state
Token bucket: Average rate plus controlled bursts
Leaky bucket: Smooths output toward a configured rate