What is rate-limiter-flexible?
The rate-limiter-flexible npm package is a powerful and flexible rate limiting library for Node.js. It supports various backends like Redis, MongoDB, and in-memory storage, making it suitable for distributed systems. It helps in controlling the rate of requests to APIs, preventing abuse, and ensuring fair usage.
What are rate-limiter-flexible's main functionalities?
Basic Rate Limiting
This feature allows you to set up basic rate limiting using in-memory storage. The example limits a user to 5 requests per second.
const { RateLimiterMemory } = require('rate-limiter-flexible');
const rateLimiter = new RateLimiterMemory({
points: 5, // 5 points
duration: 1, // Per second
});
rateLimiter.consume('user-key')
.then(() => {
// Allowed
})
.catch(() => {
// Blocked
});
Rate Limiting with Redis
This feature demonstrates how to use Redis as a backend for rate limiting. The example limits a user to 10 requests per minute.
const { RateLimiterRedis } = require('rate-limiter-flexible');
const Redis = require('ioredis');
const redisClient = new Redis();
const rateLimiter = new RateLimiterRedis({
storeClient: redisClient,
points: 10, // 10 points
duration: 60, // Per minute
});
rateLimiter.consume('user-key')
.then(() => {
// Allowed
})
.catch(() => {
// Blocked
});
Rate Limiting with MongoDB
This feature shows how to use MongoDB as a backend for rate limiting. The example limits a user to 5 requests per minute.
const { RateLimiterMongo } = require('rate-limiter-flexible');
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/rate-limiter', { useNewUrlParser: true, useUnifiedTopology: true });
const rateLimiter = new RateLimiterMongo({
storeClient: mongoose.connection,
points: 5, // 5 points
duration: 60, // Per minute
});
rateLimiter.consume('user-key')
.then(() => {
// Allowed
})
.catch(() => {
// Blocked
});
Rate Limiting with Bursts
This feature allows for burst handling by blocking the user for a specified duration if they exceed the rate limit. The example blocks a user for 10 seconds if they exceed 10 requests per second.
const { RateLimiterMemory } = require('rate-limiter-flexible');
const rateLimiter = new RateLimiterMemory({
points: 10, // 10 points
duration: 1, // Per second
blockDuration: 10, // Block for 10 seconds if consumed more than points
});
rateLimiter.consume('user-key')
.then(() => {
// Allowed
})
.catch(() => {
// Blocked
});
Other packages similar to rate-limiter-flexible
express-rate-limit
express-rate-limit is a basic rate-limiting middleware for Express applications. It is simpler and less flexible compared to rate-limiter-flexible, but it is easier to set up for basic use cases.
rate-limiter
rate-limiter is another rate limiting library for Node.js. It is less feature-rich compared to rate-limiter-flexible and does not support as many backends, but it is straightforward to use for simple rate limiting needs.
bottleneck
bottleneck is a powerful rate limiting and job scheduling library for Node.js. It offers more advanced features like priority queues and job scheduling, making it more suitable for complex use cases compared to rate-limiter-flexible.
node-rate-limiter-flexible
Flexible rate limiter with Redis as broker allows to control requests rate in cluster or distributed environment.
Backed on native Promises
It uses fixed window to limit requests.
Installation
npm i rate-limiter-flexible
Usage
Redis client must be created with offline queue switched off
const redis = require('redis');
const { RateLimiter } = require('rate-limiter-flexible');
const redisClient = redis.createClient({ enable_offline_queue: false });
redisClient.on('error', (err) => {
});
const opts = {
limit: 5,
duration: 5,
};
const rateLimiter = new RateLimiter(redisClient, opts);
rateLimiter.consume(remoteAddress)
.then(() => {
rateLimiter.penalty(remoteAddress, 3);
rateLimiter.reward(remoteAddress, 2);
})
.catch((err, msBeforeReset) => {
if (err) {
} else {
const secs = Math.round(msBeforeReset / 1000) || 1;
res.set('Retry-After', String(secs));
res.status(429).send('Too Many Requests');
}
});
API
rateLimiter.consume(key, rate)
Returns Promise, which:
- resolved when point(s) is consumed, so action can be done
- rejected when some Redis error happened. Callback is
(err)
- rejected when there is no points to be consumed.
Callback is
(err, msBeforeReset)
, where msBeforeReset
is number of ms before next allowed request
Arguments:
key
is usually IP address or some unique client idrate
number of points consumed. default: 1
rateLimiter.penalty(key, rate = 1)
Fine key
by rate
number of points.
Doesn't return anything
rateLimiter.reward(key, rate = 1)
Reward key
by rate
number of points.
Doesn't return anything