Overview

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.