Rate Limiting Algorithms
Token bucket, leaky bucket, sliding window counter, fixed window -- tradeoffs, boundary bursts, and Redis-based distributed rate limiting patterns.
Overview
Overview Rate limiting controls how frequently a client can perform an action within a time window. It protects API servers from abuse, ensures fair resource sharing among tenants, and prevents single clients from exhausting server capacity.
Four fundamental algorithms: Fixed window counter divides time into discrete buckets and counts requests -- simple but allows boundary bursts. Sliding window log tracks every request timestamp -- accurate but memory-intensive. Sliding window counter approximates the sliding window by interpolating between two adjacent fixed window counts -- efficient and nearly accurate. Token bucket maintains a bucket that refills at a fixed rate; each request consumes a token, allowing bursts up to the bucket size. Leaky bucket queues requests and drains at a fixed rate regardless of burst -- smoothing traffic for rate-sensitive downstreams.
In distributed systems, rate limiting must be distributed. Local-only state on each API gateway instance enforces N times the limit when traffic is load-balanced across N instances. Redis atomic operations (INCR+EXPIRE for fixed window, Lua scripts for token bucket) provide shared state with sub-millisecond lookup latency.
Key concepts
- Token Bucket
- A bucket with capacity N tokens refills at a fixed rate (e.g., 100 tokens/sec). Each request consumes a token. If empty, reject. The bucket accumulates up to N tokens during idle periods, allowing short bursts. Token bucket is the most common algorithm because it accommodates legitimate bursty traffic while enforcing a long-term average rate. AWS API Gateway uses token bucket (burst capacity + steady-state RPS limits).
- Sliding Window Counter
- Approximates a sliding window using two fixed window counters. Estimate for the last 60 seconds: prev_count * (1 - elapsed_fraction) + current_count. Small error (< 1% at low rates) but uses only two Redis keys instead of a full timestamp log. Used by Cloudflare for distributed rate limiting because it is memory-efficient and maps to two INCR+EXPIRE operations.
- Redis Lua for Atomic Rate Limiting
- Redis Lua scripts execute atomically (Redis is single-threaded). A token bucket in Redis stores (token_count, last_refill_timestamp) in a hash. The Lua script computes tokens to add since last refill, caps at bucket size, decrements if > 0, and stores the updated state. Without atomicity, two concurrent requests both reading count=99 could both be allowed, exceeding the limit. Lua eliminates this race condition.
When to use it
- Protecting an API endpoint from being hammered by misbehaving clients or bots.
- Implementing usage-based billing tiers (100 req/min free, 10,000 req/min paid).
- Designing a rate limiter in a system design interview -- classic question.
- Configuring Envoy local rate limiting or global rate limit service in Kubernetes.
Interview questions
- Design a distributed rate limiter allowing 100 requests per minute per user across 10 API gateway instances.
Sign up free to read the full topic
More Networking topics
Start free on Cariara · Coding problems · System design studio