call(back)
Algorithms & Data StructuresmediumSign in to star problems

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 allow refills 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.

Asked at