Table of contents In this article, we will show how to rate limit your Next.js API routes using the Upstash Rate limit SDK
Database Setup
Create a Redis database using Upstash Console or Upstash CLI . Copy the UPSTASH_REDIS_REST_URL
and UPSTASH_REDIS_REST_TOKEN
for the next steps.
Project Setup
We will create a Next.js application and deploy to Vercel.
npx create-next-app@latest
Install @upstash/ratelimit:
npm install @upstash/ratelimit @upstash/redis
The Code
Update your pages/api/hello.js
as below and replace UPSTASH_REDIS_REST_URL
and UPSTASH_REDIS_REST_TOKEN
.
import {Ratelimit} from "@upstash/ratelimit";
import {Redis} from "@upstash/redis";
const redis = new Redis({
url: 'UPSTASH_REDIS_REST_URL',
token: 'UPSTASH_REDIS_REST_TOKEN',
})
// Create a new ratelimiter, that allows 5 requests per 5 seconds
const ratelimit = new Ratelimit({
redis: redis,
limiter: Ratelimit.fixedWindow(5, "5 s"),
});
export default async function handler(req, res) {
// Use a constant string to limit all requests with a single ratelimit
// Or use a userID, apiKey or ip address for individual limits.
const identifier = "api";
const result = await ratelimit.limit(identifier);
res.setHeader('X-RateLimit-Limit', result.limit)
res.setHeader('X-RateLimit-Remaining', result.remaining)
if (!result.success) {
res.status(200).json({message: 'The request has been rate limited.', rateLimitState: result})
return
}
res.status(200).json({name: 'John Doe', rateLimitState: result})
}
Here, we allow 5 requests per 5 seconds.
Run
Run the app with npm run dev
. Refresh the browser more than 5 times and you will see the rate limiting in action.
{"message":"The request has been rate limited.","rateLimitState":{"success":false,"limit":5,"remaining":-1,"reset":1654546770000,"pending":{}}}
Possible Enhancements
Use your user's id or IP address as identifier to limit the usage per user.
const identifier = getClientIp ( req );
const result = await ratelimit . limit ( identifier );
const ratelimit = new Ratelimit ({
redis : redis ,
limiter : Ratelimit . slidingWindow ( 10 , " 10 s " ),
});
const ratelimit = new Ratelimit ({
redis : redis ,
limiter : Ratelimit . tokenBucket ( 5 , " 10 s " , 10 ),
});
Use multiple Redis in different regions if your Next.js application is deployed to different regions. This will help you to minimize latency for different locations.
Keep and read your Upstash Redis credentials from environment variables or secret store.