Controlling the flow into the network
If every sender transmitted as fast as it liked, routers would overflow. Networks therefore shape or police traffic. The token bucket is the most widely used method, found in routers, API rate limiters and cloud gateways.
The algorithm
- A bucket holds up to B tokens (the bucket size) and starts full.
- Every tick, r new tokens are added. If the bucket is full the extra tokens are lost.
- To send a packet, take one token out. If there is none, the packet is dropped (or queued).
tokens ← B
every tick:
tokens ← min(B, tokens + r)
for each arriving packet:
if tokens ≥ 1: tokens ← tokens − 1; send
else: drop
Worked example
Bucket size 5, rate 1, arrivals per tick: 4, 4, 0, 0, 1, 0, 5, 0, 0, 1.
| Tick | Arrivals | Sent | Dropped | Tokens left |
|---|---|---|---|---|
| 1 | 4 | 4 | 0 | 1 |
| 2 | 4 | 2 | 2 | 0 |
| 3 | 0 | 0 | 0 | 1 |
| 4 | 0 | 0 | 0 | 2 |
| 5 | 1 | 1 | 0 | 2 |
| 6 | 0 | 0 | 0 | 3 |
| 7 | 5 | 4 | 1 | 0 |
| 8–10 | 0, 0, 1 | 1 | 0 | 2 |
Total: 12 sent, 3 dropped. The idle ticks 3–6 let the bucket refill, which paid for the burst at tick 7.
Token bucket vs leaky bucket
| Token bucket | Leaky bucket | |
|---|---|---|
| Output | Bursts allowed, up to the bucket size | Constant rate |
| Idle time | Saved as tokens | Wasted |
| Typical use | Rate limiting APIs and routers | Smoothing traffic into a fixed pipe |
Tuning
- Rate r sets the long-run average the sender may use.
- Size B sets how large a burst is tolerated. A big bucket is friendly to bursty applications but can hit the network with a large spike.
Compare this with TCP congestion control, where the sender slows itself down after losses instead of being limited by a router.
Code
class TokenBucket:
def __init__(self, size, rate):
self.size, self.rate, self.tokens = size, rate, size
def tick(self):
self.tokens = min(self.size, self.tokens + self.rate)
def allow(self):
if self.tokens >= 1:
self.tokens -= 1
return True
return False
Common mistakes
- Thinking the bucket holds packets. It holds permission tokens.
- Forgetting the cap: tokens beyond the bucket size are discarded, so idle time cannot be saved forever.
- Confusing the two buckets: only the leaky bucket forces a constant output rate.
Complexity at a glance
| Case / operation | Time | Why |
|---|---|---|
| Per packet | O(1) | Check and decrement a counter. |
| Maximum burst | bucket size | A full bucket lets that many packets go at once. |
| Long-run average rate | token rate | Never more than the tokens added per tick. |
| Extra space | O(1) — one counter and a timestamp |
Quick check
Test yourself — pick an answer to see if you got it.
1. What happens to a packet when the bucket has no tokens (in the policing version)?
Without a token the packet is non-conforming, so it is dropped (or queued if the router is shaping).
2. What does the bucket size control?
The size is the number of tokens that can accumulate, so it is the largest burst.
3. How is a token bucket different from a leaky bucket?
A leaky bucket smooths traffic to a fixed rate, while a token bucket saves up unused capacity as tokens so that bursts can pass.
4. A bucket of size 5 is full and 7 packets arrive in one tick (refill rate 1). How many are sent?
The bucket can never hold more than 5 tokens, so the refill adds nothing. Five packets get a token and the other two are dropped.