Per-IP / Per-User Limits Out of the Box
@fastify/rate-limit
Track requests per key and return 429 responses with a Retry-After header. Use the built-in memory store for one process, or Redis for many.
What you'll learn
- Install @fastify/rate-limit
- Configure max requests and a timeWindow
- Use the Redis store for multi-instance deployments
Rate limiting protects you from accidental client misuse and deliberate abuse. @fastify/rate-limit tracks request counts per key (the IP by default) and returns 429 with Retry-After once limits are exceeded.
Install & Register
npm install @fastify/rate-limit import rateLimit from '@fastify/rate-limit'
await app.register(rateLimit, {
max: 100,
timeWindow: '1 minute',
}) That gives every IP 100 requests per minute. After that the plugin replies with 429 and a Retry-After header.
Redis for Multi-Instance
In-memory counters work for a single process. When you run multiple replicas, share state through Redis.
import Redis from 'ioredis'
await app.register(rateLimit, {
redis: new Redis(app.config.REDIS_URL),
max: 1000,
timeWindow: '1 minute',
nameSpace: 'rl:',
}) Per-User Keys
Keying by IP is unfair behind NATs. After you authenticate, key by user ID:
await app.register(rateLimit, {
max: 600,
timeWindow: '1 minute',
keyGenerator: (req) => {
const user = req.user as { sub?: string } | undefined
return user?.sub ?? req.ip
},
}) You can also attach a stricter limit to a single sensitive route with app.rateLimit({ max: 5, timeWindow: '1 minute' }) in config.