Skip to content

Instantly share code, notes, and snippets.

@chandelabhishek
Created May 3, 2024 06:50
Show Gist options
  • Select an option

  • Save chandelabhishek/6d6ddb818542078f13b95341423a4039 to your computer and use it in GitHub Desktop.

Select an option

Save chandelabhishek/6d6ddb818542078f13b95341423a4039 to your computer and use it in GitHub Desktop.
sliding window rate limter using redis and nodejs
/**
* parameters for both functions:
* 1. isOverTheLimit
* 2. addRequestToRateLimitWndow
*
* is a key, which represents the key on which the rate limiter should be working.
* e.g.
* 1. if you want to rate limit a specific api, say, /v1/api then key is simply : `/v1/api`
* 2. if you want to rate limit a specific api and IP address, then key can a combination of both viz.: `/v1/api:34.10.43.23`
*
* above can be extend to your usecase.
*
*/
const { createClient } = require("redis");
const { v4 } = require("uuid");
const { REDIS_URL, RATE_LIMITER_WINDOW, RATE_LIMITER_MAX_ALLOWED_REQUESTS } =
process.env;
const slidingWindow = parseInt(RATE_LIMITER_WINDOW, 10);
const maxRequests = parseInt(RATE_LIMITER_MAX_ALLOWED_REQUESTS, 10);
function closeRedisConnection() {
redis.quit();
}
module.exports = async function getRateLimiter() {
const redis = createClient({ url: REDIS_URL });
await redis.connect();
/**
*
* @returns boolean -- true/false based on if synthesia sign api can be called
*/
async function isOverTheLimit(key) {
const currentTime = await redis.time();
const [_, cardinality] = await redis
.multi()
.zRemRangeByScore(key, 0, currentTime - slidingWindow)
.zCard(key)
.expire(key, Math.floor(slidingWindow / 1000))
.exec();
if (cardinality >= maxRequests) return true;
return false;
}
/**
* Increases the count of the request in the given window
*/
async function addRequestToRateLimitWndow(key) {
const currentTime = await redis.time();
await redis.zAdd(key, {
score: currentTime.getTime(),
value: `${v4()}`,
});
}
return { isOverTheLimit, addRequestToRateLimitWndow };
};
process.on("cleanup", () => closeRedisConnection());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment