System Design
Rate Limiter (Token Bucket)
O(1) time and space per request — you just update a couple of numbers, no matter how many requests you have handled.
The idea, in plain English
Picture a bucket that holds a few tokens. Each time you make a request, you spend one token. If the bucket is empty, you must wait — the system blocks you. The bucket slowly refills over time, one token at a time. So after a short wait, you can make requests again. This is a rate limiter. It lets you burst a lot of requests for a short time. But it stops anyone from hammering the system nonstop.
How it works
- 1Give each user (or API key) a bucket with a maximum size — say, 3 tokens.
- 2When a request comes in, first refill the bucket a little. Base the refill on the time since the last check: elapsed time ÷ refill rate = new tokens. Never go above the bucket's capacity.
- 3If the bucket has at least one token, take one and allow the request. If the bucket is empty, block the request.
When you'd use it
Use a rate limiter when your app gets popular. One user, or one buggy script, could send your server thousands of requests a second. A rate limiter protects everyone else by capping how fast any single caller can go.
Common beginner mistakes
- Using the real system clock makes examples and tests unpredictable. In production, you read the real clock. But always pass the time in as a value, so your logic stays testable.
- Forgetting to cap the bucket at its maximum size. Without a cap, tokens would pile up forever if nobody used the API for a while.
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, refills 1 token every 10 ticks
t=0: allowed (tokens left: 2)
t=1: allowed (tokens left: 1)
t=2: allowed (tokens left: 0)
t=15: allowed (tokens left: 0)
t=16: blocked (tokens left: 0)
t=40: allowed (tokens left: 2)Not sure this is the right topic? See the learning paths → or where this leads →