This set of packages provides flexible and highly customizable rate-limiting solutions for Node.js applications. The core package, @canmertinyo/rate-limiter-core, includes the in-memory implementation. To enable storage-backed rate limiting, you can integrate it with either @canmertinyo/rate-limiter-mongo for MongoDB, @canmertinyo/rate-limiter-redis for Redis, or @canmertinyo/rate-limiter-memcached for Memcached.
Option | Type | Description | Default Value | Example |
---|---|---|---|---|
ms |
number |
Time window in milliseconds for rate limiting. | 60000 (1 minute) |
ms: 60000 |
maxRequest |
number |
Maximum requests allowed within the time window. | 10 |
maxRequest: 10 |
storage |
object |
Storage manager for rate limits (e.g., in-memory, MongoDB, Redis, Memcached). | undefined (in-memory) |
storage: mongoStorage |
message |
string |
Custom message returned when rate limit is exceeded. | "Too many requests" |
message: "Too many requests, please try again later." |
statusCode |
number |
HTTP status code for rate limit responses. | 429 |
statusCode: 429 |
keyGenerator |
function |
Function to generate a unique key for rate limiting (e.g., based on req.ip or headers). |
(req) => req.ip |
keyGenerator: (req) => req.ip |
skip |
function |
Function to bypass rate limiting for certain requests (e.g., based on user role). | undefined |
skip: (req) => req.headers["x-user-role"] === "admin" |
errorHandler |
function |
Error handling function for issues from the storage layer. | Logs error and proceeds. | errorHandler: (req, res, next) => next() |
passOnStoreError |
boolean |
Whether to allow requests to pass even if the storage fails. | false |
passOnStoreError: true |
To install (Core version only in memory):
npm install @canmertinyo/rate-limiter-core
To install (Mongo store):
npm install @canmertinyo/rate-limiter-mongo mongoose
To install (Redis store)
npm install @canmertinyo/rate-limiter-redis ioredis
To install (Memcached store)
npm install @canmertinyo/rate-limiter-memcached memcached
import express from "express";
import { rateLimiter } from "@canmertinyo/rate-limiter-core";
const app = express();
// Apply rate limiter middleware
app.use(
rateLimiter({
ms: 60000, // Time in milliseconds
maxRequest: 5, // Maximum requests allowed within the time
//DEFAULT IS IN MEMORY
})
);
app.get("/", (req, res) => {
res.send("Welcome to the API!");
});
app.listen(3000, () => {
console.log("Server is running on http://localhost:3000");
});
import express from "express";
import { RedisStorage } from "@canmertinyo/rate-limiter-redis";
import { rateLimiter } from "@canmertinyo/rate-limiter-core";
const app = express();
const port = 3001;
// Configure the rate limiter with Redis storage
app.use(
rateLimiter({
ms: 5000, // Time window in milliseconds
maxRequest: 2, // Maximum requests allowed in the time window
storage: new RedisStorage({ host: "127.0.0.1", port: 6379 }), // Redis configuration
})
);
// Sample route
app.get("/", (req, res) => {
res.send("Hello World!");
});
// Start the server
app.listen(port, () => {
console.log(`Server listening on port ${port}`);
});
import express from "express";
import { MongoStorage } from "@canmertinyo/rate-limiter-mongo";
import { rateLimiter } from "@canmertinyo/rate-limiter-core";
const app = express();
const port = 3001;
// MongoDB connection string (replace with your MongoDB URL)
const mongoUrl = "mongodb://your-mongodb-url";
app.use(
rateLimiter({
ms: 5000, // Time window in milliseconds
maxRequest: 2, // Maximum requests allowed in the time window
storage: new MongoStorage(mongoUrl), // MongoDB configuration
})
);
// Sample route
app.get("/", (req, res) => {
res.send("Hello World!");
});
// Start the server
app.listen(port, () => {
console.log(`Server listening on port ${port}`);
});
app.use(
rateLimiter({
ms: 60000, // Time window in milliseconds
maxRequest: 10, // Maximum requests allowed
storage: mongoStorage, // Use MongoDB or Redis as storage or just leave it as empty. it will behave in memory storage
message: "Too many requests, please try again later.", // Custom rate limit message
statusCode: 429, // OPTIONAL: You can fully optimize HTTP status code for rate limit response
keyGenerator: (req) => req.ip, //OPTIONAL : Custom key generator
skip: (req) => {
//OPTIONAL :
const userRole = req.headers["x-user-role"]; // Assume user role is passed in headers
return userRole === "admin"; // Skip rate limiting for admin users
},
errorHandler: (req, res, next) => {
console.error("Rate limiter error");
next();
}, // Handle errors from storage
passOnStoreError: true, // Pass requests even if storage fails
})
);
import express from "express";
import { MemcachedStore } from "@canmertinyo/rate-limiter-memcached";
import { rateLimiter } from "@canmertinyo/rate-limiter-core";
const app = express();
const port = 3001;
// Configure the rate limiter with Memcached storage
app.use(
rateLimiter({
ms: 5000, // Time window in milliseconds
maxRequest: 2, // Maximum requests allowed in the time window
storage: new MemcachedStore("127.0.0.1:11211", { //optons for customize db behaivor }), // Memcached configuration
})
);
// Sample route
app.get("/", (req, res) => {
res.send("Hello World!");
});
// Start the server
app.listen(port, () => {
console.log(`Server listening on port ${port}`);
});