Description
Description
This not an bug, but just an issue I faced, which will hopefully save somebody hours of work.
For most this is probably already obvious, but you need to create a new RedisStore
for each limiter.
You cannot define a RedisStore
and then re-use it accross all limiters. This does NOT work:
const defaultSettings = {
standardHeaders: true,
legacyHeaders: false,
store: new RedisStore({
sendCommand: (...args: string[]) => client.sendCommand(args),
prefix: 'rateLimit:',
}),
};
const limiterOne = rateLimit({
...defaultSettings,
windowMs: 24 * 60 * 60 * 1000, // 24 hours
max: 500,
});
const limiterTwo = rateLimit({
...defaultSettings,
windowMs: 60 * 1000, // 1 min
max: 10,
});
It doesn't work, because RedisStore
reads the windowMs
property when initializing, and uses it to set reset-timer
. Without it, the reset-timer
is set by default to 24 hours. Additionally, in the above example the RedisStore
would always use the same key prefix
, which means that different API routes would count towards the same limit.
So in short, you always need to create a new RedisStore
with each limiter.
const defaultSettings = {
standardHeaders: true,
legacyHeaders: false,
};
const limiterOne = rateLimit({
...defaultSettings,
windowMs: 24 * 60 * 60 * 1000, // 24 hours
max: 500,
store: new RedisStore({
sendCommand: (...args: string[]) => client.sendCommand(args),
prefix: 'rateLimitOne:',
}),
});
const limiterTwo = rateLimit({
...defaultSettings,
windowMs: 60 * 1000, // 1 min
max: 10,
store: new RedisStore({
sendCommand: (...args: string[]) => client.sendCommand(args),
prefix: 'rateLimitTwo:',
}),
EXTRA
You can extract the sendCommand
function to re-use it across all new RedisStores
.
const defaultSettings = {
standardHeaders: true,
legacyHeaders: false,
};
const sendCommand = (...args) => client.sendCommand(args);
const limiterOne = rateLimit({
...defaultSettings,
windowMs: 24 * 60 * 60 * 1000, // 24 hours
max: 500,
store: new RedisStore({
sendCommand,
prefix: 'rateLimitOne:',
}),
});
const limiterTwo = rateLimit({
...defaultSettings,
windowMs: 60 * 1000, // 1 min
max: 10,
store: new RedisStore({
sendCommand,
prefix: 'rateLimitTwo:',
}),