Every API you call eventually tells you to slow down. Sometimes it’s a polite 429. Sometimes it’s a ban. Before you reach for a library, it’s worth knowing how little code a solid rate limiter takes.
The idea
A token bucket is a simple mental model:
A bucket holds up to capacity tokens.
Tokens drip in at a steady rate per second.
Each request costs one token.
No tokens? Wait until one arrives.
The bucket allows short bursts (up to capacity) while enforcing a long-term average rate, which is how most real APIs behave.
The code
python
import time
import threading
class TokenBucket:
def init (self, rate: float, capacity: int):
self.rate = rate # tokens added per second
self.capacity = capacity # max tokens in the bucket
self.tokens = capacity
self.updated = time.monotonic()
self.lock = threading.Lock()
def _refill(self): now = time.monotonic() elapsed = now - self.updated self.tokens = min(self.capacity, self.tokens + elapsed * self.rate) self.updated = now
def acquire(self, cost: int = 1):…