Rate limiting without a database

3 October 2026

For a small API you rarely need Redis to stop one client from hammering you. Keep a dictionary of buckets in memory, keyed by client address. Each bucket stores a token count and the time of the last refill.

def allow(key, rate=5, burst=20):
    now = time.monotonic()
    tokens, last = buckets.get(key, (burst, now))
    tokens = min(burst, tokens + (now - last) * rate)
    if tokens < 1:
        buckets[key] = (tokens, now)
        return False
    buckets[key] = (tokens - 1, now)
    return True

Run one worker, or pin clients to a worker, and expire old keys once a minute. When you outgrow this, move the dictionary to a shared store; the logic stays the same.

← All notes