Skip to content

Rate Limit Plugin

Rate limiting solution with fixed window, sliding window, and token bucket algorithms for protecting APIs and enforcing usage quotas.

Overview

The Rate Limit Plugin provides distributed rate limiting backed by Redis, ensuring consistent enforcement across all application instances. Useful for API protection and resource quota management.

ChallengeWithout Rate LimitingWith Rate Limit Plugin
API AbuseInfrastructure costs increaseUsage controlled per client
Unfair UsageSingle client monopolizes resourcesFair distribution enforced
Bot ScrapingData harvested without limitsAutomated requests throttled

Key Features

  • Multiple Algorithms — Fixed window, sliding window, and token bucket strategies
  • Flexible Key Extraction — Rate limit by IP, user ID, API key, or custom identifiers
  • Standard HeadersX-RateLimit-* and Retry-After headers
  • Distributed State — Consistent limits across all application instances via Redis
  • Configurable Responses — Custom error messages and status codes
  • Skip Conditions — Bypass rate limits for specific requests or users

Installation

bash
npm install @nestjs-redisx/core @nestjs-redisx/rate-limit ioredis
bash
npm install @nestjs-redisx/core @nestjs-redisx/rate-limit redis

Basic Configuration

typescript
import { Module } from '@nestjs/common';
import { RedisModule } from '@nestjs-redisx/core';
import { RateLimitPlugin } from '@nestjs-redisx/rate-limit';

@Module({
  imports: [
    RedisModule.forRoot({
      clients: {
        host: 'localhost',
        port: 6379,
      },
      plugins: [
        new RateLimitPlugin({
          defaultAlgorithm: 'sliding-window',
          defaultPoints: 100,
          defaultDuration: 60,
          includeHeaders: true,
        }),
      ],
    }),
  ],
})
export class AppModule {}

Usage with Decorator

typescript
import { Controller, Get } from '@nestjs/common';
import { RateLimit } from '@nestjs-redisx/rate-limit';

@Controller('api')
export class ApiController {
  @Get('public')
  @RateLimit({ points: 10, duration: 60 })
  getPublicData() {
    // 10 requests per minute per IP
    return { data: 'public' };
  }

  @Get('authenticated')
  @RateLimit({ points: 1000, duration: 60, key: 'user' })
  getAuthenticatedData() {
    // 1000 requests per minute per user
    return { data: 'authenticated' };
  }
}

Usage with Guard

typescript
import { Controller } from '@nestjs/common';
import { RateLimit } from '@nestjs-redisx/rate-limit';

@Controller('api')
@RateLimit({ points: 100, duration: 60 })
export class ApiController {
  // All routes protected with 100 req/min
}

Response Headers

Successful requests include rate limit information:

http
HTTP/1.1 200 OK
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 75
X-RateLimit-Reset: 1706123456

Rate-limited requests return appropriate status:

http
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1706123456
Retry-After: 45

Algorithm Comparison

AlgorithmDescriptionBest For
Fixed WindowReset at fixed intervalsSimple use cases
Sliding WindowRolling window calculationMost API rate limiting
Token BucketTokens replenish over timeBurst handling

Documentation

TopicDescription
Core ConceptsUnderstanding rate limiting
ConfigurationConfiguration reference
@RateLimit DecoratorRoute-level rate limiting
RateLimitGuardController-level protection
Service APIProgrammatic rate checking
AlgorithmsAlgorithm comparison
Key ExtractionCustom key strategies
Response HeadersHeader configuration
MonitoringMetrics and observability
TestingTesting rate-limited endpoints
RecipesImplementation examples
TroubleshootingDebugging common issues

Released under the MIT License.