API Rate Limiting – Request Throttling in 2026

February 08, 202611 min readURL: /en/blog/api-rate-limiting-request-throttling-2026
Autor: DevStudio.itWeb & AI Studio

What is Rate Limiting? How it works, strategies, implementation in Node.js, Express, Next.js, Redis and best practices for secure APIs.

rate limitingapi securityddos protectionredisexpressnextjsapi best practices

TL;DR

Rate Limiting is restricting the number of API requests in a given time. It protects against abuse, DDoS and ensures fair resource access. Here's how to implement rate limiting in 2026.

Who this is for

  • Developers building public APIs
  • Teams needing protection against abuse
  • Companies offering API as product
  • Projects requiring cost control

Keyword (SEO)

rate limiting, api rate limit, ddos protection, api security, throttling, express rate limit, redis rate limiting

What is Rate Limiting?

Rate Limiting is:

  • Limiting the number of requests in time
  • Protection against abuse and DDoS
  • Fair access to resources
  • Cost control for infrastructure

Example:

Limit: 100 requests per minute
User 1: 50 requests ✅
User 2: 150 requests ❌ (blocked after 100)

Why Rate Limiting?

1. Protection against abuse

Scenarios:

  • Bot scraping data
  • Brute force attacks
  • API abuse
  • Unauthorized access

Without rate limiting:

Attacker: 10,000 requests/second
Server: Overloaded, crash

With rate limiting:

Attacker: 10,000 requests/second
Rate limiter: Blocks after 100/min
Server: Works normally

2. Cost control

Problem:

  • Each request costs (compute, database)
  • Unlimited API = unlimited costs
  • Difficult budget control

Solution:

  • Limits per user
  • Resource usage control
  • Predictable costs

3. Fair access

For all users:

  • One user cannot monopolize API
  • Equal resource access
  • Better experience

4. Error prevention

Protection against:

  • Accidental infinite loop
  • Client code errors
  • Improper API usage

Rate Limiting strategies

1. Fixed Window

How it works:

  • Time window (e.g. 1 minute)
  • Counter resets each window
  • Simple to implement

Example:

Window: 1 minute
Limit: 100 requests
00:00-00:59: 100 requests ✅
01:00-01:59: Reset, new 100 requests ✅

Problem:

  • Burst at window boundaries
  • Possible 200 requests in 2 seconds (at end and start of window)

2. Sliding Window

How it works:

  • Window sliding in time
  • Counts requests from last N seconds
  • More fair

Example:

Limit: 100 requests per 60 seconds
00:00: 50 requests (available: 50)
00:30: 30 requests (available: 20)
01:00: 20 requests (available: 0, blocked)
01:30: Requests from 00:30 expire (available: 20)

3. Token Bucket

How it works:

  • Bucket with tokens
  • Tokens added at constant rate
  • Request consumes token
  • No tokens = blocked

Example:

Capacity: 100 tokens
Adding: 10 tokens/second
Request: 1 token

4. Leaky Bucket

How it works:

  • Bucket with hole
  • Requests enter bucket
  • Constant leak rate
  • Full bucket = blocked

Implementation

1. Express.js with express-rate-limit

Installation:

npm install express-rate-limit

Basic usage:

import rateLimit from 'express-rate-limit';

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // 100 requests per window
  message: 'Too many requests, please try again later.',
  standardHeaders: true,
  legacyHeaders: false,
});

app.use('/api/', limiter);

Different limits for different endpoints:

// General limit
const generalLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 100,
});

// Stricter limit for auth
const authLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 5, // Only 5 login attempts
  skipSuccessfulRequests: true,
});

app.use('/api/', generalLimiter);
app.use('/api/auth/login', authLimiter);

With Redis (for multiple instances):

npm install express-rate-limit redis
import RedisStore from 'rate-limit-redis';
import { createClient } from 'redis';

const redisClient = createClient();
await redisClient.connect();

const limiter = rateLimit({
  store: new RedisStore({
    client: redisClient,
    prefix: 'rl:',
  }),
  windowMs: 15 * 60 * 1000,
  max: 100,
});

2. Next.js API Routes

Middleware approach:

// lib/rateLimit.ts
import { NextRequest, NextResponse } from 'next/server';
import { Ratelimit } from '@upstash/ratelimit';
import { Redis } from '@upstash/redis';

const redis = new Redis({
  url: process.env.UPSTASH_REDIS_REST_URL!,
  token: process.env.UPSTASH_REDIS_REST_TOKEN!,
});

const ratelimit = new Ratelimit({
  redis,
  limiter: Ratelimit.slidingWindow(10, '10 s'),
});

export async function rateLimit(request: NextRequest) {
  const ip = request.ip ?? '127.0.0.1';
  const { success, limit, remaining } = await ratelimit.limit(ip);
  
  if (!success) {
    return NextResponse.json(
      { error: 'Too many requests' },
      { status: 429 }
    );
  }
  
  return { limit, remaining };
}

Usage in API route:

// app/api/users/route.ts
import { rateLimit } from '@/lib/rateLimit';

export async function GET(request: NextRequest) {
  const rateLimitResult = await rateLimit(request);
  
  if (rateLimitResult instanceof NextResponse) {
    return rateLimitResult; // Rate limit exceeded
  }
  
  // Normal logic
  return NextResponse.json({ users: [] });
}

3. Custom implementation with Redis

Sliding window log:

import { createClient } from 'redis';

const redis = createClient();
await redis.connect();

async function checkRateLimit(
  key: string,
  limit: number,
  windowSeconds: number
): Promise<{ allowed: boolean; remaining: number }> {
  const now = Date.now();
  const windowStart = now - windowSeconds * 1000;
  
  // Remove old requests
  await redis.zRemRangeByScore(key, 0, windowStart);
  
  // Count current requests
  const count = await redis.zCard(key);
  
  if (count >= limit) {
    return { allowed: false, remaining: 0 };
  }
  
  // Add new request
  await redis.zAdd(key, {
    score: now,
    value: `${now}-${Math.random()}`,
  });
  
  // Set TTL
  await redis.expire(key, windowSeconds);
  
  return { allowed: true, remaining: limit - count - 1 };
}

// Usage
const result = await checkRateLimit('user:123', 100, 60);
if (!result.allowed) {
  return res.status(429).json({ error: 'Rate limit exceeded' });
}

Best Practices

1. Different limits for different endpoints

Strategy:

const limits = {
  public: { windowMs: 15 * 60 * 1000, max: 100 },
  auth: { windowMs: 15 * 60 * 1000, max: 5 },
  upload: { windowMs: 60 * 60 * 1000, max: 10 },
  search: { windowMs: 60 * 1000, max: 20 },
};

2. User identification

Methods:

  • IP address (for public APIs)
  • API key (for authorized)
  • User ID (for logged in)
  • Session ID

Example:

function getIdentifier(req: Request): string {
  // Priority: API key > User ID > IP
  return (
    req.headers.get('x-api-key') ||
    req.user?.id ||
    req.ip ||
    'anonymous'
  );
}

3. Informational headers

Standard headers:

res.setHeader('X-RateLimit-Limit', '100');
res.setHeader('X-RateLimit-Remaining', '50');
res.setHeader('X-RateLimit-Reset', resetTime);

4. Graceful degradation

Instead of completely blocking:

if (rateLimitExceeded) {
  // Option 1: Queue request
  await queueRequest(request);
  
  // Option 2: Throttle (slow down)
  await sleep(1000);
  
  // Option 3: Return cached data
  return getCachedResponse();
}

5. Monitoring and alerts

Track:

  • Number of blocked requests
  • Top users/IPs
  • Abuse patterns
  • Performance impact

Rate Limiting vs Throttling

Rate Limiting Throttling
Blocks after limit Slows down requests
Hard limit Soft limit
429 status Delays response
For security For performance

FAQ

What limits to set?

Depends on case:

  • Public API: 100-1000/min
  • Auth endpoints: 5-10/min
  • Upload: 10-50/hour
  • Search: 20-100/min

What to do when limit exceeded?

  • Return 429 status
  • Add Retry-After header
  • Inform user
  • Offer upgrade plan

Does rate limiting slow down API?

Minimally (usually <1ms). Worth using Redis for cache and fast checking.

How to test rate limiting?

// Test
for (let i = 0; i < 150; i++) {
  const res = await fetch('/api/endpoint');
  if (i >= 100) {
    expect(res.status).toBe(429);
  }
}

Want to implement Rate Limiting in your API?

About the author

We build fast websites, web/mobile apps, AI chatbots and hosting setups — with a focus on SEO and conversion.

Recommended links

If you want to go from knowledge to implementation — here are shortcuts to our products, hosting and portfolio.

Want this implemented for your business?

Let’s do it fast: scope + estimate + timeline.

Get Quote