Next.js API Rate Limiting with Middleware

Search for a command to run...

No comments yet. Be the first to comment.
GraphQL has become a popular choice for managing API requests, thanks to its flexibility and efficiency in querying data. Combining GraphQL with Next.js allows developers to build powerful, scalable applications. In this guide, we’ll explore how to i...
If you’re building modern web applications, chances are you’ve needed a simple backend for tasks like storing form submissions, feedback requests, or lightweight data logs. Instead of spinning up a server or managing databases, what if you could just...

Real-time applications, such as chat apps, require instant data exchange between clients and servers. In this guide, we'll walk through integrating Socket.io with Next.js (App Router) to build a real-time chat application. 🚀 Why Use Socket.io with ...

Managing global state in a Next.js application can be tricky, but Redux Toolkit (RTK) makes it easier by reducing boilerplate and improving performance. In this guide, we’ll walk through integrating Redux Toolkit with Next.js to efficiently manage ap...

Firebase is a powerful backend-as-a-service platform that offers authentication, real-time databases, and hosting. Integrating Firebase with a Next.js application allows you to build scalable and serverless web applications with ease. Why Use Fireba...

Optimization in Next.js App

As your application scales, managing API usage becomes crucial to maintain performance and security. Rate limiting is a key strategy to control the frequency of API requests, prevent abuse, and ensure fair usage among clients. In this guide, we’ll explore how to implement API rate limiting in a Next.js application using middleware.
Rate limiting restricts the number of API requests a client can make within a specific time window. For example, you might allow a maximum of 100 requests per user per minute. If the limit is exceeded, the server responds with an error or throttles further requests.
Improved Performance: Prevents server overload by controlling traffic.
Security: Mitigates denial-of-service (DoS) attacks and other abuse.
Fair Usage: Ensures all clients have equitable access to resources.
Starting from Next.js 13, middleware provides an efficient way to process requests before they reach API routes or pages. We’ll leverage middleware to implement rate limiting.
We’ll use the upstash/ratelimit package along with Upstash Redis for rate limiting. Install the required packages:
npm install @upstash/redis @upstash/ratelimit
Create an account on Upstash.
Set up a new Redis database and note the connection URL and token.
Create a middleware.ts file in the src directory to handle rate limiting.
// src/middleware.ts
import { NextResponse } from 'next/server';
import { Redis } from '@upstash/redis';
import { Ratelimit } from '@upstash/ratelimit';
// Initialize Redis client
const redis = new Redis({
url: process.env.UPSTASH_REDIS_URL!,
token: process.env.UPSTASH_REDIS_TOKEN!,
});
// Initialize Ratelimit with Redis store
const ratelimit = new Ratelimit({
redis,
limiter: Ratelimit.fixedWindow(100, '1 m'), // 100 requests per minute
});
export default async function middleware(req: Request) {
const ip = req.headers.get('x-forwarded-for') || req.ip || 'unknown';
// Check rate limit for the IP address
const { success, reset } = await ratelimit.limit(ip);
if (!success) {
return NextResponse.json(
{ error: 'Too many requests. Please try again later.' },
{ status: 429, headers: { 'Retry-After': String(reset) } }
);
}
return NextResponse.next();
}
export const config = {
matcher: '/api/:path*', // Apply middleware only to API routes
};
IP-Based Rate Limiting: The middleware extracts the client’s IP address and checks its request count using the ratelimit instance.
Fixed Window: The rate limiter allows a maximum of 100 requests per IP per minute.
Response on Exceeding Limit: If the client exceeds the limit, a 429 Too Many Requests response is returned, with a Retry-After header indicating when they can retry.
Add the following environment variables to your .env.local file:
UPSTASH_REDIS_URL=<your-upstash-redis-url>
UPSTASH_REDIS_TOKEN=<your-upstash-redis-token>
Start the Server: Run the development server:
npm run dev
Send API Requests: Use a tool like curl or Postman to send requests to an API route (e.g., /api/example).
Check Rate Limiting: After exceeding 100 requests per minute, you should receive a 429 Too Many Requests error.
curl -X GET http://localhost:3000/api/example
Instead of IP-based rate limiting, you can use a user’s authentication token or unique identifier.
const userId = req.headers.get('authorization') || 'unknown';
const { success, reset } = await ratelimit.limit(userId);
You can customize rate limits for specific routes by modifying the middleware’s matcher configuration or checking the request URL.
if (req.nextUrl.pathname.startsWith('/api/private')) {
// Stricter rate limit for private APIs
const { success, reset } = await ratelimit.limit(ip, { requests: 50 });
// ...
}
Monitor Usage: Regularly review rate limit metrics to adjust limits as needed.
Graceful Messaging: Provide informative error messages and retry headers.
Test Thoroughly: Simulate high traffic to ensure the middleware handles edge cases.
Implementing API rate limiting in Next.js with middleware ensures secure and scalable API usage. By leveraging Upstash Redis and the @upstash/ratelimit package, you can effectively manage traffic and protect your application from abuse. Whether you’re building public APIs or internal tools, rate limiting is a vital strategy for maintaining performance and fairness.