You’re on-call for a fintech payments API handling 5M daily active users and bursty traffic during payroll days. A small set of “hot” API keys can suddenly generate huge request spikes, causing CPU thrash and P99 latency regressions. To protect the system, you’re asked to implement an in-memory rate limiter that efficiently rejects requests when a key exceeds its allowed request rate.
Design a function that processes a stream of request events and returns whether each request should be allowed or blocked.
Implement:
rate_limit(events, limit, window_seconds, ttl_seconds) -> list[bool]Where:
events is a list of (timestamp, api_key) pairs sorted by non-decreasing timestamp.api_key in the time interval (timestamp - window_seconds, timestamp] is < limit.api_key has had no requests for ttl_seconds, its state must be eligible for removal to prevent memory growth.Return a boolean list aligned with events indicating allow/block.
Input:
events = [(1,"A"),(2,"A"),(3,"A"),(4,"A"),(5,"A")]limit = 3, window_seconds = 4, ttl_seconds = 10Output:
[True, True, True, False, True]Explanation:
At t=4, key A has allowed requests at t=1,2,3 within (0,4] → 3 already, so the 4th is blocked. At t=5, the window is (1,5], so t=1 is out; only t=2,3 remain → allow.
Input:
events = [(1,"A"),(2,"B"),(12,"A"),(13,"A")]limit = 2, window_seconds = 10, ttl_seconds = 8Output:
[True, True, True, True]Explanation:
Key A is idle from t=1 to t=12 (11 seconds). Since ttl_seconds=8, its state can be dropped and rebuilt at t=12.
1 <= len(events) <= 2 * 10^50 <= timestamp <= 10^9api_key is a non-empty string, total characters across all keys <= 2 * 10^51 <= limit <= 10^51 <= window_seconds <= 10^91 <= ttl_seconds <= 10^9events are sorted by time; multiple events may share the same timestamp.