Rate Limiting — Protect Your Node.js API
Advertisement
Rate limiting prevents abuse and DDoS attacks. Essential for production APIs.
express-rate-limit
npm install express-rate-limit
import rateLimit from "express-rate-limit";
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // Limit each IP to 100 requests per windowMs
message: "Too many requests",
standardHeaders: true, // Return rate limit info in headers
legacyHeaders: false,
});
app.use(limiter);
// Stricter limit for login
const loginLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 5,
skipSuccessfulRequests: true, // Don't count successful logins
});
app.post("/login", loginLimiter, (req, res) => {
// Handle login
});
Redis-based Rate Limiting
import RedisStore from "rate-limit-redis";
import { createClient } from "redis";
const redisClient = createClient();
const limiter = rateLimit({
store: new RedisStore({
client: redisClient,
prefix: "rl:", // Key prefix
}),
windowMs: 60 * 1000, // 1 minute
max: 30,
});
app.use(limiter);
Custom Rate Limit
async function checkRateLimit(
key: string,
limit = 100,
window = 3600
): Promise<boolean> {
const current = await redis.incr(key);
if (current === 1) {
await redis.expire(key, window);
}
return current <= limit;
}
app.use(async (req, res, next) => {
const allowed = await checkRateLimit(`ip:${req.ip}`);
if (!allowed) {
return res.status(429).json({ error: "Too many requests" });
}
next();
});
User-level Rate Limiting
app.post("/api/data", async (req: any, res) => {
if (!req.user) return res.status(401).json({ error: "Not auth" });
const allowed = await checkRateLimit(
`user:${req.user.id}:api`,
1000, // 1000 requests per hour
3600
);
if (!allowed) {
return res.status(429).json({ error: "API quota exceeded" });
}
// Process request
});
FAQ
Q: Should rate limiting be on server or reverse proxy? A: Both. Proxy catches obvious abuse, server handles legitimate users.
Q: How do I handle bursts? A: Use sliding window or token bucket algorithms.
Q: What about different plans? A: Store plan info with user, apply different limits per plan.
Rate limiting is non-negotiable for production APIs. Implement it from day one.
Advertisement