Node.js6 min read

Rate Limiting in Node.js APIs

Protect your API from abuse with rate limiting. Implement request throttling and prevent DDoS attacks.

Sarah Chen
December 19, 2025
0.0k0

Rate Limiting in Node.js APIs

Rate limiting prevents abuse by limiting how many requests a client can make.

Setup

```bash npm install express-rate-limit ```

Basic Rate Limiter

```javascript const rateLimit = require('express-rate-limit');

const limiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 100, // 100 requests per window message: { error: 'Too many requests, please try again later' } });

// Apply to all requests app.use(limiter); ```

API-Specific Limits

```javascript // Strict limit for auth routes const authLimiter = rateLimit({ windowMs: 60 * 60 * 1000, // 1 hour max: 5, // 5 attempts message: { error: 'Too many login attempts' } });

app.use('/api/auth', authLimiter);

// Relaxed limit for general API const apiLimiter = rateLimit({ windowMs: 60 * 1000, // 1 minute max: 60 // 60 requests per minute });

app.use('/api', apiLimiter); ```

Custom Key Generator

```javascript const limiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 100, keyGenerator: (req) => { // Rate limit by user ID if authenticated, IP otherwise return req.user?.id || req.ip; } }); ```

Skip Certain Requests

```javascript const limiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 100, skip: (req) => { // Don't rate limit admins return req.user?.role === 'admin'; } }); ```

Custom Response Headers

```javascript const limiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 100, standardHeaders: true, // Return rate limit info in headers legacyHeaders: false // Disable X-RateLimit headers });

// Response headers: // RateLimit-Limit: 100 // RateLimit-Remaining: 99 // RateLimit-Reset: 1234567890 ```

Redis Store (for distributed apps)

```bash npm install rate-limit-redis ```

```javascript const RedisStore = require('rate-limit-redis'); const redis = require('redis');

const client = redis.createClient();

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

Different Limits by Plan

```javascript const createLimiter = (max) => rateLimit({ windowMs: 60 * 1000, max, keyGenerator: (req) => req.user?.id || req.ip });

const limiters = { free: createLimiter(10), pro: createLimiter(100), enterprise: createLimiter(1000) };

function dynamicRateLimit(req, res, next) { const plan = req.user?.plan || 'free'; return limiters[plan](req, res, next); }

app.use('/api', dynamicRateLimit); ```

Slow Down Instead of Block

```bash npm install express-slow-down ```

```javascript const slowDown = require('express-slow-down');

const speedLimiter = slowDown({ windowMs: 15 * 60 * 1000, delayAfter: 50, // Allow 50 requests without delay delayMs: (hits) => hits * 100 // Add 100ms per request after 50 });

app.use(speedLimiter); ```

Complete Setup

```javascript const rateLimit = require('express-rate-limit');

// General API limit app.use('/api', rateLimit({ windowMs: 60 * 1000, max: 60, standardHeaders: true }));

// Strict auth limit app.use('/api/auth/login', rateLimit({ windowMs: 15 * 60 * 1000, max: 5, message: { error: 'Too many login attempts. Try again in 15 minutes.' } }));

// Very strict for password reset app.use('/api/auth/forgot-password', rateLimit({ windowMs: 60 * 60 * 1000, max: 3 })); ```

Key Takeaway

Rate limiting is essential API security. Use express-rate-limit for quick setup. Apply stricter limits to sensitive endpoints (auth, payments). Use Redis store for distributed systems. Always return informative error messages.

#Node.js#Express#Rate Limiting#Security#Intermediate