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
npm install express-rate-limit
Basic Rate Limiter
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
// 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
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
const limiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 100,
skip: (req) => {
// Don't rate limit admins
return req.user?.role === 'admin';
}
});
Custom Response Headers
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)
npm install rate-limit-redis
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
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
npm install express-slow-down
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
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