Design a distributed rate limiter that caps how many requests a client (API key / IP) can make per time window.
How to approach it
Design the API and data model from the user’s actions, not from the database. Name the few core endpoints, the entities and their keys/indexes, and — critically — which data must be strongly consistent versus eventually consistent. The access pattern (how you read the data) should drive the storage choice, not the other way around.
Core APIs
| Endpoint | Purpose |
|---|---|
| INTERNAL allow(clientId, route) | returns allow/deny + retry-after |
| GET /limits/{tier} | read configured limits |
Entities
| Entity | Keys / indexes |
|---|---|
| Counter (key=client:route:window, count, expires) | Redis key with TTL = window |
| LimitConfig (tier, route, limit, window) | cached in-process |
Note
Counters are best-effort; a tiny overcount under races is acceptable for most limits.