Rate limiting
How it works#
The limiter runs as an atomic Redis Lua script: ZREMRANGEBYSCORE to drop expired entries, ZCARD to count what remains, and ZADD to record the current call, all in one round trip. There is no check-then-set gap for concurrent requests to slip through.
Every response carries X-RateLimit-* headers so clients can back off before they get a 429.
Per-plan limits#
Limits live in PLAN_RATE_LIMITS in seed.ts, alongside your plan quotas. Anonymous traffic has its own set in ANONYMOUS_RATE_LIMITS. Both are marked as customization points, see configuration.
Fail-open, on purpose#
The rate limiter fails open: if Redis is unreachable, requests pass. Quota enforcement fails closed: if the quota check cannot run, the request is rejected.
That asymmetry is deliberate. A Redis outage should not take your product down, but it also should not hand out unlimited paid usage. The trade-off is documented in code so you can invert it if your risk profile differs.
Related: security decisions, known trade-offs.