Here's a simple way to do rate limiting based on a key and using incr.
by Rick Blalock · 11/15/2021
I needed to do quick and simple rate-limiting this week. Here's a solution I came to, using Upstash.
js1import upstash from '@upstash/redis';2
3const redis = upstash({4 url: process.env.UPSTASH_REST_URL,5 token: process.env.UPSTASH_REST_TOKEN,6});7
8export const hashKey = (apiKey: string, minute: number) => {9 return `limits:${apiKey}:${minute}`;10};11
12export const checkLimit = async (apiKey: string) => {13 const minute = new Date().getMinutes();14 const key = hashKey(apiKey, minute);15 const currentLimit = await redis.get(key);16
17 // Test if limit is reached and throw error if it is18 if (currentLimit.data) {19 const count = parseInt(currentLimit.data, 10);20 if (count > 1000) { // 1000 requests per minute21 console.error('todo, handle overage here');22 }23 }24
25 // Increment the rate limit counter and ensure it expires in 59 min26 // Note that if the key is not found, it will be created27 redis.incr(key);28 redis.expire(key, 59 * 60); // Expire in 59 minutes29
30 return currentLimit.data ? parseInt(currentLimit.data, 10) : 1;31};
I assume you can do the same thing with Redis (maybe using something like ioredis
npm). You
can probably optimize it further by using MULTI
(i.e. transactions), so it all will happen in one swoop.
Sign up and get the latest friction log studies, blog articles and podcast updates