Rate Limiting in Fastify That Actually Works
@fastify/rate-limit + Redis is the production-grade combo. Here's the config that handles trust proxy, per-route limits, and per-user keys correctly.
Rate Limiting in Fastify That Actually Works
@fastify/rate-limit is the standard. Here's the production config.
Setup
npm install @fastify/rate-limit ioredis
import Fastify from 'fastify';
import rateLimit from '@fastify/rate-limit';
import Redis from 'ioredis';
const app = Fastify({ trustProxy: 1 });
await app.register(rateLimit, {
global: true,
max: 100,
timeWindow: '1 minute',
redis: new Redis(process.env.REDIS_URL),
keyGenerator: (req) => {
const user = (req).user; // if you've set this in an auth hook
return user?.id || req.ip;
},
skipOnError: true, // fail open if Redis is down
});
Per-route limits
Stricter on auth routes:
app.post('/auth/login', {
config: {
rateLimit: {
max: 5,
timeWindow: '5 minutes',
},
},
}, async (req, reply) => {
// login handler
});
What skipOnError does
When Redis is unreachable, the rate limiter fails open by default — requests pass through unrestricted. This prevents Redis becoming a hard dependency for your app's availability. Tradeoff: during a Redis outage, rate limits are temporarily disabled.
Verifying
for i in {1..15}; do curl -i http://localhost:3000/auth/login -d 'foo'; done
After the limit, you'll see 429 Too Many Requests with X-RateLimit-* headers indicating when to retry.
Related
Frequently Asked Questions
Does @fastify/rate-limit support per-route limits?
Yes — pass a config object to specific routes via `config.rateLimit`. Different limits per endpoint without separate plugin registrations.
Should I use the built-in store or Redis?
Redis for multi-instance. The built-in LRU store is in-memory and per-process.
What about per-user rate limiting?
Pass a `keyGenerator` function that returns the user ID for authenticated requests, falling back to IP.
Recommended reading
If your team uses Sentry for frontend errors and needs backend distributed tracing without doubling the Sentry bill, here's the OpenTelemetry path that doesn't make you choose.
May 9Five approaches to bot blocking in Express, ranked by effort vs. effectiveness. From a 5-line allowlist to a full IP-reputation firewall — all without Cloudflare, AWS WAF, or any new infrastructure.
May 9Fastify hooks (onRequest) and the SecureNow preload both work cleanly. Here's the production setup for IP blocking and user-agent filtering.
May 9