Node.js cookbook · Beginner
Rate limit an Express API across instances
Throttle login attempts and API calls per client, shared across all Node processes.
Approach
Use express-rate-limit with a Redis store (rate-limit-redis) so counts are shared across processes and servers. Apply a strict limiter to auth routes and a looser one globally, key by user/API key when authenticated, and enable standard RateLimit headers. Configure trust proxy correctly so client IPs are real.
Solution
import express from "express";
import { rateLimit } from "express-rate-limit";
import { RedisStore } from "rate-limit-redis";
import { createClient } from "redis";
const redis = createClient({ url: process.env.REDIS_URL });
await redis.connect();
const store = (prefix: string) =>
new RedisStore({ prefix, sendCommand: (...args: string[]) => redis.sendCommand(args) });
const app = express();
app.set("trust proxy", 1); // one proxy hop (e.g. the load balancer)
app.use("/api", rateLimit({
windowMs: 60_000,
limit: 300,
standardHeaders: "draft-8",
legacyHeaders: false,
keyGenerator: (req) => req.get("x-api-key") ?? req.ip!,
store: store("rl:api:"),
}));
app.post("/api/auth/login", rateLimit({
windowMs: 15 * 60_000,
limit: 10,
skipSuccessfulRequests: true, // count only failed attempts
store: store("rl:login:"),
}), loginHandler);
Pitfalls
- Memory store with multiple processes (cluster/PM2/Kubernetes).
trust proxyset totrueblindly (clients can spoof X-Forwarded-For).- Keying by IP only for APIs used from shared NATs.
Variations
- Fastify:
@fastify/rate-limitwith Redis. - Edge/gateway rate limiting (Cloudflare, API Gateway) for coarse protection.
Further reading: express-rate-limit
Reference: https://express-rate-limit.mintlify.app/overview
More Node.js recipes
- Add health and readiness endpoints to a Node.js service
- Add JWT authentication to an Express API
- Cache expensive lookups in Redis from Node.js
- Call external APIs with timeouts and retries in Node.js
- Centralize error handling in Express 5
- Hash passwords and implement login safely in Node.js
- Implement cursor pagination with PostgreSQL in Node.js
- Offload CPU-heavy work with worker threads