Building a Rate Limiter in Node.js With Redis and Express Middleware
Rate limiting is essential for protecting your API from abuse and ensuring fair usage. In this tutorial, we'll build a basic but powerful rate limiter using Express.js middleware and Redis to track requests in real time.
Why Use Redis for Rate Limiting?
Redis is fast, in-memory, and supports operations like incrementing counters and setting expirations — perfect for rate limiting logic.
Step 1: Set Up Your Project
mkdir express-redis-rate-limiter
cd express-redis-rate-limiter
npm init -y
npm install express redis dotenv
Create a .env
file with your Redis connection details:
REDIS_URL=redis://localhost:6379
Step 2: Create the Rate Limiting Middleware
// rateLimiter.js
const redis = require("redis");
const client = redis.createClient({ url: process.env.REDIS_URL });
client.connect();
const rateLimiter = (limit, windowInSeconds) => {
return async (req, res, next) => {
const ip = req.ip;
const key = `rate-limit:${ip}`;
const current = await client.incr(key);
if (current === 1) {
await client.expire(key, windowInSeconds);
}
if (current > limit) {
return res.status(429).json({ message: "Too many requests" });
}
next();
};
};
module.exports = rateLimiter;
Step 3: Apply It in Your Express App
// index.js
require("dotenv").config();
const express = require("express");
const rateLimiter = require("./rateLimiter");
const app = express();
const PORT = process.env.PORT || 3000;
app.use(rateLimiter(100, 60)); // 100 requests per 60 seconds
app.get("/", (req, res) => {
res.send("Welcome! You are within the rate limit.");
});
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
Testing the Rate Limiter
Use a tool like ab
(ApacheBench) or curl
in a loop to simulate requests and watch the limiter in action. After 100 requests in a minute, it should block subsequent ones.
Conclusion
You've now built a rate limiter that's scalable, fast, and production-ready using Redis and Express. This can help mitigate DDoS attacks, prevent abuse, and keep your API responsive under load.
If this post helped you, consider supporting me: buymeacoffee.com/hexshift