BETA

Rate Limiting

SECURITY

Protect your Harpy.js application from abuse with built-in rate limiting powered by @nestjs/throttler.

Why Rate Limiting? Rate limiting helps prevent DDoS attacks, protects against brute-force attempts, and ensures fair resource usage across all users.

Installation

Install the @nestjs/throttler package in your Harpy.js project:

Using pnpm:

pnpm add @nestjs/throttler

Using npm:

npm install @nestjs/throttler

Using yarn:

yarn add @nestjs/throttler

Basic Configuration

Add the ThrottlerModule to your app.module.ts and set up the ThrottlerGuard globally:

import { Module } from '@nestjs/common';
import { ThrottlerModule, ThrottlerGuard } from '@nestjs/throttler';
import { APP_GUARD } from '@nestjs/core';

@Module({
  imports: [
    ThrottlerModule.forRoot([
      {
        ttl: 10000,  // Time window in milliseconds (10 seconds)
        limit: 10,   // Maximum requests per time window
      },
    ]),
    // ... your other modules
  ],
  providers: [
    {
      provide: APP_GUARD,
      useClass: ThrottlerGuard,
    },
  ],
})
export class AppModule {}

Note: With this configuration, all routes in your application will be limited to 10 requests per 10 seconds by default.

Custom Rate Limits per Route

You can override the default limits for specific routes using the @Throttle decorator:

import { Controller, Get } from '@nestjs/common';
import { Throttle } from '@nestjs/throttler';

@Controller('api')
export class ApiController {
  // Allow 50 requests per 10 seconds for this endpoint
  @Get('data')
  @Throttle({ default: { limit: 50, ttl: 10000 } })
  getData() {
    return { message: 'Data endpoint' };
  }

  // Skip rate limiting for this endpoint
  @Get('public')
  @Throttle({ default: { limit: 0 } })
  getPublicData() {
    return { message: 'Public endpoint - no rate limit' };
  }
}

Configuration Options

OptionTypeDescription
ttlnumberTime window in milliseconds (e.g., 10000 = 10 seconds)
limitnumberMaximum number of requests allowed per time window
ignoreUserAgentsRegExp[]Array of user agent patterns to exclude from rate limiting
skipIfFunctionFunction returning boolean to conditionally skip throttling

Advanced Configuration

Here's an example with multiple throttle configurations and conditional skipping:

ThrottlerModule.forRoot([
  {
    name: 'short',
    ttl: 1000,   // 1 second
    limit: 3,
  },
  {
    name: 'medium',
    ttl: 10000,  // 10 seconds
    limit: 20,
  },
  {
    name: 'long',
    ttl: 60000,  // 1 minute
    limit: 100,
  },
])

Testing Rate Limits

When a rate limit is exceeded, the API will return a 429 (Too Many Requests) status code:

{
  "statusCode": 429,
  "message": "ThrottlerException: Too Many Requests"
}

Best Practice: Always implement proper error handling on the client side to gracefully handle 429 responses and inform users about rate limits.

Real-world Use Cases

🔐 Authentication Endpoints

Protect login routes from brute-force attacks with stricter limits:

@Throttle({ default: { limit: 5, ttl: 60000 } })

📧 Email Sending

Prevent spam by limiting contact form submissions:

@Throttle({ default: { limit: 3, ttl: 3600000 } }) // 3 per hour

🔍 Search APIs

Balance between user experience and resource protection:

@Throttle({ default: { limit: 30, ttl: 10000 } })

Additional Resources

Installation

Install the @nestjs/throttler package:

pnpm add @nestjs/throttler

Basic Configuration

Add the ThrottlerModule to your app.module.ts:

import { ThrottlerModule, ThrottlerGuard } from '@nestjs/throttler';
import { APP_GUARD } from '@nestjs/core';

@Module({
  imports: [
    ThrottlerModule.forRoot([
      {
        ttl: 10000,  // Time to live: 10 seconds
        limit: 10,   // Maximum 10 requests per TTL
      },
    ]),
    // ... other modules
  ],
  providers: [
    {
      provide: APP_GUARD,
      useClass: ThrottlerGuard,
    },
  ],
})
export class AppModule {}

Custom Rate Limits per Route

Apply different rate limits to specific routes using the @Throttle decorator:

import { Throttle, SkipThrottle } from '@nestjs/throttler';

@Controller('api')
export class ApiController {
  // Allow 5 requests per 60 seconds for this endpoint
  @Throttle({ default: { limit: 5, ttl: 60000 } })
  @Get('sensitive-data')
  getSensitiveData() {
    return { data: 'Protected content' };
  }

  // Skip rate limiting for specific routes
  @SkipThrottle()
  @Get('public-data')
  getPublicData() {
    return { data: 'Public content' };
  }
}

Configuration Options

OptionTypeDescription
ttlnumberTime to live in milliseconds
limitnumberMaximum number of requests within TTL
ignoreUserAgentsRegExp[]Array of user agents to ignore

💡 Best Practice: Adjust rate limits based on your application needs. API endpoints may need stricter limits than public pages. Monitor your application's traffic patterns and adjust accordingly.

Learn More