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.

Lhoussine
May 9, 2026·4 min read

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

Adding Backend Tracing to a Sentry Stack with OpenTelemetry

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 9
How to Block Bot Traffic in Express With No Extra Infra

Five 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 9
How to Block Bot Traffic in Fastify With No Extra Infra

Fastify hooks (onRequest) and the SecureNow preload both work cleanly. Here's the production setup for IP blocking and user-agent filtering.

May 9