System Design
Leaky Bucket (Rate Limiter)
O(1) time per request, averaged over many requests · O(capacity) space to hold the queued requests.
The idea, in plain English
Picture a bucket with a small hole in the bottom. It drips water out at a steady rate, no matter how fast you pour water in. Requests are like water being poured in. If they arrive faster than the hole can drain them, the bucket fills up. Once it's full, any extra water spills over the top and is lost — the request gets blocked. This differs from the token bucket rate limiter. A token bucket lets you save up tokens while idle, then use them all in one big burst. A leaky bucket always lets requests out at the same steady drip. No bursts, ever.
How it works
- 1Keep a queue — the bucket — with a maximum size, and a fixed 'leak rate.' The leak rate is how often one waiting request drains out and gets processed.
- 2When a new request arrives, first drain out any requests that should already have leaked, based on how much time has passed.
- 3If there's room left after draining, add the new request to the back of the queue. It will be processed in its turn. If the bucket is still full, reject the request — it spills over.
When you'd use it
Use a leaky bucket once your app is popular and needs to call a downstream service — like a payment gateway or a partner API — that can only handle a steady stream of requests, and would choke on even a short burst. A leaky bucket smooths out bursty incoming traffic into one constant, predictable rate. A token bucket, by contrast, would let a burst straight through.
Common beginner mistakes
- Mixing this up with the token bucket. The token bucket is built to allow bursts. The leaky bucket is built to flatten bursts into one steady rate.
- Forgetting to drain old requests before checking whether there's room. That makes the bucket look fuller than it is, and rejects requests that should have been allowed.
Try it — edit and run
Click the code to edit · press ⌘/Ctrl+↵ to run
Editable code. Tab and Shift+Tab indent. Press Escape, then Tab, to move focus out of the editor.
Bucket: capacity 3, leaks 1 request every 10 ticks
t=0: allowed (queue size: 1)
t=1: allowed (queue size: 2)
t=2: allowed (queue size: 3)
t=3: blocked (queue size: 3)
t=15: allowed (queue size: 3)
t=16: blocked (queue size: 3)Not sure this is the right topic? See the learning paths → or where this leads →