Implementing Rate Limiting
1. Understanding Rate Limit Strategies
| Algorithm | Detail |
|---|---|
| Fixed window | N requests / minute |
| Sliding window | Smoother, more accurate |
| Token bucket | Allows bursts up to bucket size |
| Leaky bucket | Constant outflow rate |
2. Implementing IP-based Limits
| Pattern | Detail |
|---|---|
| Anonymous traffic | Default key when no user |
| CDN forwarded | Use CF-Connecting-IP / X-Forwarded-For |
| IPv6 | Hash /64 prefix to avoid abuse |
3. Implementing User-based Limits
Example: User rate limit
const limiter = new RateLimiterRedis({
storeClient: redis,
keyPrefix: "user_rl",
points: 100,
duration: 60
});
context: async ({ req }) => {
const user = await auth(req);
await limiter.consume(user?.id ?? req.ip);
return { user };
}
4. Implementing Query Complexity Limits
| Approach | Detail |
|---|---|
| Per-query cap | Reject queries above cost threshold |
| Cost budget | N cost units per minute per user |
| Cost-aware billing | Tier limits by plan |
5. Using Rate Limit Headers
| Header | Detail |
|---|---|
| X-RateLimit-Limit | Max in window |
| X-RateLimit-Remaining | Tokens left |
| X-RateLimit-Reset | Unix time of reset |
| Retry-After | Seconds to wait (on 429) |
6. Implementing Throttling
| Pattern | Detail |
|---|---|
| Queue + delay | Slow down rather than reject |
| Concurrency cap | Max N in-flight per user |
| Tier-based | Free vs paid limits |
7. Whitelisting Queries
| Pattern | Detail |
|---|---|
| Persisted query allowlist | Reject any non-allowlisted query |
| Deploy-time | Build allowlist from client codegen |
| Block introspection | Disable in production |
8. Handling Rate Limit Errors
Example: Throw rate-limit error
throw new GraphQLError("Rate limit exceeded", {
extensions: { code: "RATE_LIMITED", http: { status: 429, headers: { "Retry-After": "30" } } }
});
9. Using Redis for Rate Limiting
| Library | Detail |
|---|---|
| rate-limiter-flexible | Multiple algorithms, Redis backend |
| @upstash/ratelimit | Edge-friendly |
| Lua script | Atomic INCR + EXPIRE |
10. Implementing Burst Limits
| Setting | Detail |
|---|---|
| Sustained rate | e.g. 60/min |
| Burst capacity | Bucket size, e.g. 30 in 10 s |
| Refill rate | Tokens added per second |