Implement Api Rate Limiting with Upstash Redis in your Next.js project
Efficiently Manage API Traffic: Implement Rate Limiting with Upstash Redis in Your Next.js Project
Table of contents
What is Rate Limiting?
Suppose you have a application where a user can post his picture, for this action you are calling an api endpoint running on a server and the endpoint stores the post in the database.
Now lets say the user posting the picture spams the post button and the server recieves thousands of requests per second, potentially overwhelming the server and causing it to crash or become unresponsive for other users.
To avoid the above scenario Rate Limiting is used!!
Setup
Create a boilerplate Next.js project using:
npx create-next-app@latest
Install @upstash/redis and @upstash/ratelimit using:
npm i @upstash/redis @upstash/ratelimit
docs - https://upstash.com/blog/upstash-ratelimit
Implementation of rate limiting
Since we are using nextjs the demonstration of implementation will be using server actions.
so, go ahead create a folder of actions and creates a server action which posts a picture or content to the database(Highly suggest prisma or drizzle for this).
After creating the server action follow the following steps:
create a config folder and inside it create upstash.ts file with the following code
import { Redis } from "@upstash/redis" export const redis = new Redis({ // get these credentials by creating account on upstash url: `enter your upstash db url here` token: `enter you db token here` });
Now inside your server actions file, where the action for posting is created we'll use upstash/ratelimit by doing the following:
"use server"; import { Ratelimit } from '@upstash/ratelimit'; import { redis } from './upstash'; // the file that you created above import { headers } from 'next/headers'; const ratelimit = new Ratelimit({ redis, limiter: Ratelimit.slidingWindow(5,"120s"); //this means 5 requests is allowed per 120 seconds }); export const addPost = async () => { // your server action const ip = headers().get('x-forwarded-for'); //getting user's ip const {remaining, limit, success} = await ratelimit.limit(ip!); console.log(limit) // shows max limit console.log(remaining) // shows remaining requests in the window console.log(success) // returns if able to process the request // so to implement rate limit we need to use simple if condition if(!success){ return "unable to process the request, limit reached wait for 2 minutes"; } //rest of the addPost logic should be here dealing with the database }
Note: Here we are using rate limiting which uses sliding window technique and there are many more types of rate limiting to know about them check out the following link:
types of rate limiting: https://www.imperva.com/learn/application-security/rate-limiting/
There you go!! now you know how to implement rate limiting in your large scale projects very easily without any headache.