DEV Community

Željko Šević
Željko Šević

Posted on • Originally published at sevic.dev on

8

Redis as custom storage for NestJS rate limiter

A rate limiter is a standard protection technique against brute force and DDoS attacks. NestJS provides a module for it, and the default storage is in-memory. Custom storage, Redis in this case, should be injected inside ThrottlerModule configuration.

Configuration

The configuration should contain

  • TTL (time to live) in seconds
  • maximum number of requests within TTL
  • Redis URL
// app.module.ts
import { APP_GUARD } from '@nestjs/core';
import { ThrottlerGuard, ThrottlerModule } from '@nestjs/throttler';
import { ThrottlerStorageRedisService } from 'nestjs-throttler-storage-redis';
// ...
@Module({
  imports: [
    ThrottlerModule.forRootAsync({
      inject: [CustomConfigService],
      useFactory: (configService: CustomConfigService) => ({
        ttl: configService.THROTTLER_TTL_SECONDS,
        limit: configService.THROTTLER_LIMIT,
        storage: new ThrottlerStorageRedisService(configService.REDIS_URL),
      }),
    }),
    // ...
  ],
})
export class AppModule {}
Enter fullscreen mode Exit fullscreen mode

API endpoints setup

Binding the throttler guard can be done in multiple ways.

  • guard is bound globally for every API endpoint.
// app.module
import { ThrottlerGuard } from '@nestjs/throttler';
// ...
@Module({
  // ...
  providers: [{
    provide: APP_GUARD,
    useClass: ThrottlerGuard,
  }],
})
export class AppModule {}
Enter fullscreen mode Exit fullscreen mode
  • global guard is overridden for the specific API endpoint with the Throttle decorator.
import { Throttle } from '@nestjs/throttler';
// ...
@Controller('users')
export class UsersController {
  @Throttle(USERS_THROTTLER_LIMIT, USERS_THROTTLER_TTL_SECONDS)
  @Get()
  async getUsers() {}
}
Enter fullscreen mode Exit fullscreen mode
  • global guard is skipped for the specific API endpoint with the SkipThrottle decorator.
import { SkipThrottle } from '@nestjs/throttler';
// ...
@Controller('posts')
export class PostsController {
  @SkipThrottle()
  @Get()
  async getPosts() {}
}
Enter fullscreen mode Exit fullscreen mode

Course

Build your SaaS in 2 weeks - Start Now

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read full post →

Top comments (0)

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more