A flexible and robust rate limiting middleware for Node.js applications with support for both in-memory and Redis-based storage. This rate limiter can be used in both single-server and distributed environments.
- 🚀 Simple and easy to use
- 💾 Multiple storage options (in-memory and Redis)
- 🔄 Configurable time windows and request limits
- 🎯 Multiple identifier strategies (IP, auth token, cookie)
- 🔌 Pluggable custom identifier extraction
- 🎨 Clean middleware interface
- 🔒 Thread-safe and distributed-safe (when using Redis)
- ⚡ Lightweight with minimal dependencies
npm install @sid3945/rate-limiter
import express from 'express';
import RateLimiter from '@yourusername/rate-limiter';
const app = express();
const rateLimiter = new RateLimiter({
window: 3000, // 3 seconds from the first request from this source
maxHits: 3 // 3 requests per window
});
app.use(rateLimiter.guard());
app.get('/_healthz', (req, res) => {
res.json({ message: 'Status Ok!' });
});
app.listen(3000);
const rateLimiter = new RateLimiter({
window: 3000, // Time window in milliseconds
maxHits: 3, // Maximum number of requests per window
identifier: 'ip', // Identifier strategy ('ip', 'authToken', 'cookie')
storage: 'memory' // Storage strategy ('in-memory' or 'redis')
});
const rateLimiter = new RateLimiter({
window: 3000,
maxHits: 3,
storage: 'redis',
redisConfig: {
host: 'localhost',
port: 6379,
password: 'your-password', db: 0 // Redis database number
}
});
const rateLimiter = new RateLimiter({
window: 3000,
maxHits: 3,
customIdentifierExtractor: (req) => {
return req.headers['x-custom-id'] || req.ip;
}
});
- Best for single-server deployments
- No additional dependencies
- Fast performance
- Data is lost on server restart
- Best for distributed environments
- Requires Redis server
- Consistent rate limiting across multiple servers
- Persists across server restarts
- Automatic cleanup of expired records
When rate limit is exceeded, the middleware returns:
{
error: "Too many requests",
retryAfter: 3
}
With HTTP status code 429 (Too Many Requests).
const apiLimiter = new RateLimiter({
window: 60000, // 1 minute
maxHits: 60 // 60 requests per minute
});
app.use('/api/', apiLimiter.guard());
const publicLimiter = new RateLimiter({
window: 60000,
maxHits: 30
});
const authenticatedLimiter = new RateLimiter({
window: 60000,
maxHits: 100,
identifier: 'authToken'
});
app.use('/api/public', publicLimiter.guard());
app.use('/api/private', authenticatedLimiter.guard());
- In-memory storage has minimal impact on request latency
- Redis storage adds network latency but enables distributed rate limiting
- Redis keys automatically expire after the window period
- Careful consideration needed for high-traffic applications
The middleware includes built-in error handling:
- Redis connection failures fallback to allowing requests
- Invalid configurations throw errors during initialization
- All errors are logged for debugging
Contributions are welcome! Please feel free to submit a Pull Request.
MIT
Siddharth Upadhyay
- Initial release
- Support for in-memory and Redis storage
- Basic rate limiting functionality
- Updated documentation (and reduced GEN AI footprint 😁)
- Add support for sliding windows
- Add support for multiple concurrent windows
- Add support for rate limit headers
- Add support for custom response formats