redis-sliding-window-limiter
v1.0.1
Published
Redis-based sliding window rate limiter for Node.js using Lua scripts
Maintainers
Readme
Redis Sliding Window Rate Limiter
Redis-based sliding window rate limiter using Lua for atomic execution.
Features
- Sliding window algorithm - More accurate than fixed window approach
- Redis-backed - Works across multiple instances
- Lua scripting - Atomic operations with no race conditions
- Express middleware support - Easy integration with Express.js
- Flexible client options - Supports both internal and external Redis clients
Installation
npm install redis-sliding-window-limiterBasic Usage
import { createRateLimiter } from "redis-sliding-window-limiter";
const limiter = createRateLimiter({
redisUrl: "redis://localhost:6379",
windowSize: 10,
maxRequests: 3,
});Express Middleware
Basic Usage
import express from "express";
import { createRateLimiter, createExpressMiddleware } from "redis-sliding-window-limiter";
const app = express();
prefix
const limiter = createRateLimiter({
redisUrl: "redis://localhost:6379",
windowSize: 10,
maxRequests: 3,
});
app.use(createExpressMiddleware(limiter));
app.get("/", (req, res) => {
res.json({ message: "OK" });
});
app.listen(3000, () => {
console.log("Server running on port 3000");
});Advanced Usage with Options
import express from "express";
import { createRateLimiter, createExpressMiddleware } from "redis-sliding-window-limiter";
const app = express();
const limiter = createRateLimiter({
redisUrl: "redis://localhost:6379",
windowSize: 10,
maxRequests: 3,
});
const rateLimiter = createExpressMiddleware(limiter, {
keyGenerator: (req) => req.user?.id || req.ip,
message: "Too many requests. Please try again later.",
});
app.use(rateLimiter);
app.get("/", (req, res) => {
res.json({ message: "OK" });
});
app.listen(3000, () => {
console.log("Server running on port 3000");
});Middleware Options
| Option | Type | Description |
|--------|------|-------------|
| keyGenerator | function | Custom function to generate rate limit key (default: uses IP address) |
| message | string | Custom error message when rate limit is exceeded |
Key Generator Examples:
(req) => req.user?.id- Rate limit per authenticated user(req) => req.ip- Rate limit per IP address (default)(req) => req.user?.id || req.ip- Use user ID if authenticated, otherwise IP(req) => req.headers['x-api-key']- Rate limit per API key
Using an External Redis Client
import Redis from "ioredis";
import { createRateLimiter } from "redis-sliding-window-limiter";
const redis = new Redis("redis://localhost:6379");
const limiter = createRateLimiter({
redisClient: redis,
windowSize: 10,
maxRequests: 3,
});Response Format
Allowed Request
{
"allowed": true,
"remaining": 2,
"resetTime": 1776260236828,
"limit": 3
}Rate Limit Exceeded
{
"message": "Too many requests",
"allowed": false,
"remaining": 0,
"resetTime": 1776260235374,
"limit": 3
}Configuration Options
| Option | Type | Description | Default |
|--------|------|-------------|---------|
| redisUrl | string | Redis connection string | - |
| redisClient | Redis | External Redis client instance | - |
| windowSize | number | Time window in seconds | 60 |
| maxRequests | number | Maximum requests per window | 10 |
| prefix | string | Redis key prefix | rate_limit: |
Note: Use either
redisUrlorredisClient, not both.
How It Works
- Timestamp Storage - Each request timestamp is stored in a Redis sorted set
- Window Cleanup - Old timestamps are removed using the sliding window logic
- Atomic Operations - Lua script ensures atomic execution (no race conditions)
- Request Decision - Requests are allowed or blocked based on count within the window
Algorithm Details
The sliding window algorithm works by:
- Maintaining a sorted set of request timestamps for each client
- Removing timestamps older than the current time minus the window size
- Counting remaining timestamps in the window
- Allowing or denying based on the configured limit
This approach is more accurate than fixed-window counters as it prevents the "boundary spike" problem where multiple requests at window edges can exceed the intended rate.
Links
- GitHub Repository: https://github.com/dhirajCodes543/redis-sliding-window-limiter
- npm Package: https://www.npmjs.com/package/redis-sliding-window-limiter
License
MIT
Author
Dhiraj Barnwal
