typescriptadvanced

Rate Limiter for Edge Functions

Implement sliding window rate limiting in Next.js middleware using in-memory or KV store.

typescript
// lib/rate-limit.ts
interface RateLimitConfig {
  windowMs: number;   // Time window in ms
  maxRequests: number; // Max requests per window
}

const ipRequestMap = new Map<string, { count: number; resetTime: number }>();

export function rateLimit(
  ip: string,
  config: RateLimitConfig = { windowMs: 60_000, maxRequests: 60 }
): { success: boolean; remaining: number; reset: number } {
  const now = Date.now();
  const record = ipRequestMap.get(ip);

  // Clean expired entries periodically
  if (Math.random() < 0.01) {
    for (const [key, val] of ipRequestMap) {
      if (val.resetTime < now) ipRequestMap.delete(key);
    }
  }

  if (!record || record.resetTime < now) {
    ipRequestMap.set(ip, {
      count: 1,
      resetTime: now + config.windowMs,
    });
    return { success: true, remaining: config.maxRequests - 1, reset: now + config.windowMs };
  }

  record.count++;

  if (record.count > config.maxRequests) {
    return { success: false, remaining: 0, reset: record.resetTime };
  }

  return {
    success: true,
    remaining: config.maxRequests - record.count,
    reset: record.resetTime,
  };
}

// middleware.ts
import { NextRequest, NextResponse } from 'next/server';
import { rateLimit } from '@/lib/rate-limit';

export function middleware(request: NextRequest) {
  if (request.nextUrl.pathname.startsWith('/api/')) {
    const ip = request.headers.get('x-forwarded-for') || 'unknown';
    const result = rateLimit(ip, { windowMs: 60_000, maxRequests: 30 });

    if (!result.success) {
      return NextResponse.json(
        { error: 'Too many requests' },
        {
          status: 429,
          headers: {
            'Retry-After': String(Math.ceil((result.reset - Date.now()) / 1000)),
            'X-RateLimit-Remaining': '0',
          },
        }
      );
    }
  }
  return NextResponse.next();
}

Use Cases

  • API protection
  • abuse prevention
  • cost control

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.