Beginner's Guide to Throttling in NestJS

Throttling is a common technique used in APIs to limit the number of requests a client can make within a specific time window, helping to prevent abuse, manage server load, and improve application stability. In this guide, we'll learn how to implement basic request throttling in NestJS, as well as how to skip throttling on specific routes.

Step-by-Step Throttling Implementation

Step 1: Install the Throttler Package

First, install the throttling package to add the necessary functionality to your NestJS app:

npm install @nestjs/throttler

Step 2: Configure the ThrottlerModule in AppModule

In your main application module (AppModule), import and configure the ThrottlerModule. This configuration defines how many requests are allowed within a certain time period:

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ThrottlerGuard, ThrottlerModule } from '@nestjs/throttler';
import { APP_GUARD } from '@nestjs/core';

@Module({
  imports: [
    ThrottlerModule.forRoot([{
      ttl: 20000, // Time window in seconds (20 seconds)
      limit: 2, // Maximum 2 requests per 20 seconds
    }]),
  ],
  controllers: [AppController],
  providers: [
    AppService,
    {
      provide: APP_GUARD,
      useClass: ThrottlerGuard, // Applying global throttle guard
    },
  ],
})
export class AppModule {}
  • ttl: Defines the time window in which the requests are counted. In the above example, this is set to 20 seconds.

  • limit: Defines the maximum number of requests allowed within the time window. Here, the limit is set to 2 requests.

Step 3: Apply Throttling Globally with ThrottlerGuard

The ThrottlerGuard applies throttling rules across your entire application. This is configured in the providers array of your AppModule as shown above. By using APP_GUARD, you ensure that throttling is applied globally to all routes.

Step 4: Custom Throttling on Specific Endpoints

You may want to apply different throttling rules on specific routes. This can be achieved using the @Throttle() decorator. For example, the following route has a custom throttle limit of 5 requests per 10 seconds:

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

@Controller()
export class AppController {
  @Throttle({
    default: {
      limit: 5,
      ttl: 10000,
    },
  }) // Max 5 requests per 10 seconds for this route
  @Get('limited')
  getLimitedData() {
    return 'This route has custom throttle rules!';
  }
}
  • The @Throttle(limit, ttl) decorator takes two arguments:

    • limit: Maximum number of requests.

    • ttl: Time window in seconds.

Step 5: Skipping Throttling for Specific Routes

Sometimes, you might want to skip throttling for certain routes, such as public endpoints like health checks. NestJS provides the @SkipThrottle() decorator for this purpose.

Here’s how to disable throttling for a specific route:

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

@Controller()
export class AppController {
  @SkipThrottle() // No throttling on this route
  @Get('public')
  getPublicData() {
    return 'This route is not throttled!';
  }
}

Error Handling for Throttling

If a user exceeds the defined request limits, NestJS will return an HTTP 429 Too Many Requests error with the following response:

{
  "statusCode": 429,
  "message": "Too many requests",
  "error": "Too Many Requests"
}

Step 6: Test Your Throttling Implementation

After setting up throttling, make more than the allowed number of requests within the ttl period (e.g., 2 requests within 20 seconds), and you should receive the 429 Too Many Requests error for the third request.

Conclusion

With NestJS Throttling, you can easily manage API request limits and protect your server from abuse. Here’s what we covered:

  1. Installing and configuring the @nestjs/throttler package.

  2. Setting up global throttling with ThrottlerGuard.

  3. Customizing throttling per route with the @Throttle decorator.

  4. Skipping throttling for specific routes using @SkipThrottle.

By implementing throttling, you can ensure that your application remains responsive and that resources are fairly distributed across all users.