Design a Rate Limiter
A per-user quota guard using a map of keys to recent request timestamps, with retryAfter and reset as operational escape hatches.
- Pattern
- Map key -> sliding window timestamps
- Time
- O(k) per check
- Space
- O(keys * limit)
A rate limiter is a policy wrapped around a data structure. For this drill, the policy is simple: each key gets limit requests within the last windowMs.
The recipe
Say before you type: "Prune old timestamps. If the list is under limit, push now. Otherwise deny."
Use a Map<string, number[]>.
const cutoff = nowMs - windowMs;
const fresh = hits.filter((time) => time > cutoff);
The window is half open: > and not >=, so a hit that is exactly windowMs old has already fallen out. Decide this on the first line and say it out loud, because it is not a cosmetic choice — >= keeps one stale timestamp and shifts every retryAfter answer by a millisecond.
Then allow() is just:
- Prune the key.
- If
fresh.length >= limit, returnfalse. - Push
nowMs, store the list, returntrue.
retryAfter
retryAfter() should not mutate quota. It prunes stale timestamps, then returns:
oldestHit + windowMs - nowMs
If the key is not limited, return 0.
reset
reset(key) deletes one key. reset() clears the whole map. This is the kind of operational method interviewers like because it shows you are thinking past the pure algorithm.