Tiered Token-Bucket Limiter
Implement a token-bucket rate limiter whose limits come from tiers that can change at runtime. Time is passed in explicitly, in seconds.
limiter = TieredLimiter(defaultAllow) limiter.setTier(tier, capacity, refillRate) // create or update a tier; refillRate is tokens per second limiter.assignClient(client, tier) limiter.allow(client, now) // true to serve the request, false to reject it
Rules
- A client's bucket is full the first time it is seen. Each
allowrefills it at the tier's rate for the time elapsed, never above the capacity, and takes one token if one is available. - The tier's configuration is read on every call. Lowering a capacity caps the balance at the new capacity; raising one mints no tokens.
- A client's balance travels with it when it is moved to another tier.
- A client with no tier, an unknown tier, or a tier with a negative capacity or rate gets the global fallback:
defaultAllow.
Hints
Hint 1
State per client is just (tokens, lastSeen). Refill lazily: tokens = min(capacity, tokens + (now − lastSeen) × rate), then compare with 1.
Hint 2
Look the tier up on every call rather than caching capacity in the client state — that is what makes configuration changes take effect, and the min against capacity is what makes a lowered limit bite.
Hint 3
Decide the fallback explicitly and test it: an unknown client is the most common production request, not a corner case.