Implementing Rate Limiting in Next.js App Router with In-Memory Counters 🔒⏱️
Demo :- https://ratex-nu.vercel.app/api
Codes :- https://github.com/SH20RAJ/rateLimitjs
Introduction:
Rate limiting is like a friendly bouncer at a party 🕺, making sure everyone gets a fair share of the fun without overwhelming the venue. 🏘️ It's crucial for protecting your web applications from excessive load and potential abuse, preventing Denial of Service (DoS) attacks, and ensuring the overall stability and performance of your system. 🛡️ With the introduction of the new app router in Next.js 13, implementing rate limiting may seem a bit different from the traditional approaches used in the pages router. But fear not, my friends! 💪 In this article, we'll explore how to set up rate limiting for your Next.js app router API routes using in-memory counters. 📈
Setting Up Rate Limiting with In-Memory Counters:
First things first, let's create a utility function that will handle the rate limiting logic. Create a new file called rateLimit.js in your project's utils folder (or any other location you prefer): 📂
let requestCounter = {};
let resetTimer;
const time = 5 * 1000; // 5 seconds
const requestLimit = 4; // 4 requests per 5 seconds
// Function to reset request counts
const resetCounters = () => {
requestCounter = {};
clearTimeout(resetTimer);
resetTimer = setTimeout(resetCounters, time);
};
resetCounters(); // Start the timer
export default async function rateLimit(req, res) {
const ip = (req.headers.get('x-forwarded-for') ?? '127.0.0.1').split(',')[0];
const clientIp = ({ ip }).ip;
requestCounter[clientIp] = requestCounter[clientIp] || 0;
if (requestCounter[clientIp] >= requestLimit) {
return true; // Rate limit exceeded 🚫
} else {
console.log('Request count for IP:', clientIp, '=', ++requestCounter[clientIp]);
return null; // Proceed with the request ✅
}
}
In this code:
- We initialize an empty object
requestCounterto store the request counts for each client IP address. 📋 - We define the
timevariable as5 * 1000milliseconds (5 seconds) and therequestLimitvariable as4, allowing a maximum of 4 requests per 5 seconds. ⏱️ - The
resetCountersfunction resets therequestCounterobject and sets a timeout to call itself after the specifiedtime(5 seconds in this case). 🔄 - The
rateLimitfunction is an async function that takes thereqandresobjects as parameters. 🔍 - Inside the
rateLimitfunction, we first retrieve the client's IP address from thex-forwarded-forheader or use127.0.0.1as a fallback. We then extract the first IP address from the comma-separated list (in case there are multiple IP addresses in the header). 🌐 - We initialize the request count for the client IP address to 0 if it doesn't exist in the
requestCounterobject. 🆕 - If the request count for the client IP address is greater than or equal to the
requestLimit(4 in this case), the function returnstrue, indicating that the rate limit has been exceeded. 🚫 - If the request count is below the limit, it increments the request count for the client IP address, logs the updated count, and returns
null, indicating that the request should proceed. ✅
Applying the Rate Limiting Middleware:
Now that we have the rate limiting middleware set up, we can apply it to our Next.js app router API routes. Open the route.js file for your API route and import the rateLimit function: 📝
import rateLimit from './rateLimit';
export const GET = async (req, res) => {
if (await rateLimit(req, res)) {
return new Response(JSON.stringify({ error: 'Rate limit exceeded. Please try again later.' }), {
status: 429,
headers: {
'Content-Type': 'application/json',
},
});
}
return new Response(JSON.stringify({ message: 'Hi' }), {
status: 200,
headers: {
'Content-Type': 'application/json',
},
});
};
- This file imports the
rateLimitfunction from therateLimit.jsfile. 📥 - Inside the
GETroute handler function, it calls therateLimitfunction with thereqandresobjects and awaits the result. ⏳ - If the
rateLimitfunction returnstrue(meaning the rate limit was exceeded), it returns a429 Too Many Requestsresponse with an error message. 🚫 - If the rate limit was not exceeded, it returns a
200 OKresponse with the message{ message: 'Hi' }. 👋
With this implementation, your Next.js app router API route will be protected by the rate limiting middleware, allowing a maximum of 4 requests per 5 seconds for each client IP address. 🔒
Conclusion:
Rate limiting is an essential technique for securing and optimizing your web applications, just like a friendly bouncer making sure everyone has a good time. 🕺 By following the steps outlined in this article, you can easily implement rate limiting for your Next.js app router API routes using in-memory counters. 📈 This approach is suitable for development and small-scale applications, but for production environments, it's recommended to use a more robust solution, such as a database or a dedicated rate limiting service, to ensure better scalability, persistence, and reliability. 💪
Remember, this implementation uses an in-memory counter, which means that the rate limiting will be reset when the server restarts. 🔄 Additionally, it's essential to handle the x-forwarded-for header with caution, as it can be spoofed by malicious clients. 🕵️♂️ In a production environment, it's recommended to only trust the x-forwarded-for header if you're running behind a trusted proxy server that you control. 🔐
Now go forth and implement rate limiting in your Next.js app router like a champ! 🏆 And remember, a little bit of rate limiting goes a long way in keeping your applications safe and sound. 🛡️
This technique has a catch, can you identify in comments and also has a solution. Let's increate engagement in comments. 😇😅

Top comments (2)
Great. I idea you can use Middleware + JWT(json web token), request api