CPCODELAB
Express

Rate Limiting

7 min read

Rate Limiting

Rate limiting caps how many requests a client can make in a given time window. Without it, a single actor can flood your API, exhaust your database connections, and knock your service offline. The express-rate-limit package provides a battle-tested in-process limiter with a clean API.

js
const rateLimit = require("express-rate-limit");

// Global limiter: 100 requests per 15 minutes per IP
const globalLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 100,
  standardHeaders: true,  // Return rate-limit info in RateLimit-* headers
  legacyHeaders: false,
  message: { error: "Too many requests, please try again later." }
});

app.use(globalLimiter);

// Stricter limiter for auth routes
const authLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 10,
  message: { error: "Too many login attempts." }
});

app.use("/auth", authLimiter);

For multi-server deployments, the default in-memory store is per-process. Switch to a Redis-backed store so all instances share the same counters.

js
const RedisStore = require("rate-limit-redis");
const redis = require("ioredis");

const client = new redis(process.env.REDIS_URL);

const limiter = rateLimit({
  windowMs: 60 * 1000,
  max: 60,
  store: new RedisStore({ sendCommand: (...args) => client.call(...args) })
});

Apply a tight limiter specifically to /auth/login and /auth/register. Brute-force password guessing is one of the most common API attacks, and a 10-request-per-15-minutes limit makes it effectively impractical.

Ready to test yourself?
Practice Express— quiz & coding exercises