Implement Api Rate Limiting with Upstash Redis in your Next.js project

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

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.

Did you find this article valuable?

Support Devcon blogs by becoming a sponsor. Any amount is appreciated!