Bird
Raised Fist0
NestJSframework~8 mins

Rate limiting with throttler in NestJS - Performance & Optimization

Choose your learning style10 modes available
Performance: Rate limiting with throttler
MEDIUM IMPACT
This affects server response time and client perceived latency by controlling request flow to avoid overload.
Controlling API request rate to prevent server overload
NestJS
import { ThrottlerModule, ThrottlerGuard } from '@nestjs/throttler';
import { APP_GUARD } from '@nestjs/core';
import { Module } from '@nestjs/common';

@Module({
  imports: [
    ThrottlerModule.forRoot({
      ttl: 60,
      limit: 10,
    }),
  ],
  providers: [
    {
      provide: APP_GUARD,
      useClass: ThrottlerGuard,
    },
  ],
})
export class AppModule {}
Uses optimized built-in throttler with efficient in-memory or distributed storage and minimal CPU overhead.
📈 Performance GainNon-blocking request checks; memory managed internally; stable response times under load.
Controlling API request rate to prevent server overload
NestJS
import { Injectable, NestMiddleware } from '@nestjs/common';

@Injectable()
export class RateLimitMiddleware implements NestMiddleware {
  private requests = new Map<string, number[]>();

  use(req, res, next) {
    const ip = req.ip;
    const now = Date.now();
    const windowTime = 60000; // 1 minute
    const maxRequests = 10;

    if (!this.requests.has(ip)) {
      this.requests.set(ip, []);
    }

    const timestamps = this.requests.get(ip).filter(time => now - time < windowTime);
    timestamps.push(now);
    this.requests.set(ip, timestamps);

    if (timestamps.length > maxRequests) {
      res.status(429).send('Too many requests');
    } else {
      next();
    }
  }
}
This manual approach stores timestamps in memory and filters on every request, causing CPU overhead and memory growth under load.
📉 Performance CostBlocks event loop briefly on each request; memory grows with active clients; can cause slow response under high traffic.
Performance Comparison
PatternCPU UsageMemory UsageResponse DelayVerdict
Manual timestamp filteringHigh CPU per requestGrows with clientsIncreases under load[X] Bad
NestJS ThrottlerModuleLow CPU overheadManaged internallyStable under load[OK] Good
Rendering Pipeline
Rate limiting affects server-side request handling before response rendering, impacting how quickly the server can send data back.
→Request Handling
→Response Time
⚠️ BottleneckCPU overhead during request counting and validation
Core Web Vital Affected
INP
This affects server response time and client perceived latency by controlling request flow to avoid overload.
Optimization Tips
1Use built-in throttling libraries to minimize CPU and memory overhead.
2Avoid manual timestamp filtering on every request to prevent blocking the event loop.
3Monitor 429 responses and response times in DevTools Network tab to verify throttling effectiveness.
Performance Quiz - 3 Questions
Test your performance knowledge
What is the main performance benefit of using NestJS ThrottlerModule over manual rate limiting?
AIt reduces CPU overhead by using optimized request counting
BIt increases memory usage to store more data
CIt blocks the event loop to ensure accuracy
DIt disables rate limiting under high load
DevTools: Network
How to check: Open DevTools Network tab, make rapid repeated requests to API, observe response status and timing.
What to look for: Look for 429 status codes indicating throttling and consistent response times without spikes.

Practice

(1/5)
1. What is the main purpose of using the @Throttle(ttl, limit) decorator in a NestJS application?
easy
A. To limit how many requests a user can make in a given time
B. To increase the speed of API responses
C. To log all incoming requests for debugging
D. To automatically retry failed requests

Solution

  1. Step 1: Understand the purpose of rate limiting

    Rate limiting is used to protect an app from too many requests in a short time.
  2. Step 2: Role of @Throttle(ttl, limit)

    This decorator sets how many requests are allowed within a time window (ttl).
  3. Final Answer:

    To limit how many requests a user can make in a given time -> Option A
  4. Quick Check:

    Rate limiting = request limit [OK]
Hint: Throttle controls request count per time window [OK]
Common Mistakes:
  • Confusing throttling with logging
  • Thinking it speeds up responses
  • Assuming it retries failed requests
2. Which of the following is the correct way to apply a rate limit of 10 requests per 60 seconds on a NestJS controller method?
easy
A. @Throttle(10, 60)
B. @Throttle(60, 10)
C. @Throttle(60)
D. @Throttle(limit=10, ttl=60)

Solution

  1. Step 1: Understand @Throttle(ttl, limit) parameter order

    The first parameter is ttl (time to live in seconds), second is limit (max requests).
  2. Step 2: Match parameters to desired limit

    For 10 requests per 60 seconds, ttl=60 and limit=10, so @Throttle(60, 10).
  3. Final Answer:

    @Throttle(60, 10) -> Option B
  4. Quick Check:

    ttl first, limit second = @Throttle(60, 10) [OK]
Hint: Remember: first ttl (seconds), then limit (count) [OK]
Common Mistakes:
  • Swapping ttl and limit parameters
  • Using named parameters which are unsupported
  • Providing only one parameter
3. Given the following code snippet, what will happen if a user sends 6 requests within 10 seconds?
import { Controller, Get } from '@nestjs/common';
import { Throttle } from '@nestjs/throttler';

@Controller('api')
export class ApiController {
  @Get('data')
  @Throttle(10, 5)
  getData() {
    return 'Success';
  }
}
medium
A. First 5 requests return 'Success', 6th request is blocked
B. Only the 6th request returns 'Success'
C. All requests are blocked
D. All 6 requests return 'Success'

Solution

  1. Step 1: Analyze the throttle settings

    @Throttle(10, 5) means 5 requests allowed per 10 seconds.
  2. Step 2: Evaluate request count against limit

    6 requests exceed the limit by 1, so the 6th request is blocked.
  3. Final Answer:

    First 5 requests return 'Success', 6th request is blocked -> Option A
  4. Quick Check:

    Limit 5 per 10s, 6th blocked [OK]
Hint: Requests over limit get blocked after limit reached [OK]
Common Mistakes:
  • Assuming all requests succeed
  • Thinking limit is per request instead of per time window
  • Confusing ttl and limit values
4. You added @Throttle(60, 10) to a controller method but it does not limit requests as expected. What is the most likely cause?
medium
A. The parameters are reversed; it should be @Throttle(10, 60)
B. The @Throttle decorator only works on services, not controllers
C. You forgot to import and configure ThrottlerModule in your app module
D. You need to restart the server after adding the decorator

Solution

  1. Step 1: Check if ThrottlerModule is configured

    Throttling requires ThrottlerModule.forRoot() to be imported in the app module.
  2. Step 2: Understand decorator usage and parameters

    The decorator works on controllers and methods; parameter order is correct as @Throttle(60, 10).
  3. Final Answer:

    You forgot to import and configure ThrottlerModule in your app module -> Option C
  4. Quick Check:

    Module config required for throttling [OK]
Hint: Always import ThrottlerModule to enable throttling [OK]
Common Mistakes:
  • Assuming decorator works without module setup
  • Swapping ttl and limit parameters
  • Not restarting server after changes (usually needed but not main cause)
5. You want to apply a global rate limit of 100 requests per 60 seconds for your entire NestJS app, but allow a specific controller to have a higher limit of 200 requests per 60 seconds. How should you configure this using the throttler?
hard
A. Add @Throttle(100, 60) globally and @Throttle(200, 60) on the controller
B. Set ThrottlerModule.forRoot({ ttl: 200, limit: 60 }) globally and add @Throttle(100, 60) on the controller
C. Set ThrottlerModule.forRoot({ ttl: 100, limit: 60 }) globally and add @Throttle(200, 60) on the controller
D. Set ThrottlerModule.forRoot({ ttl: 60, limit: 100 }) globally and add @Throttle(60, 200) on the specific controller

Solution

  1. Step 1: Configure global throttling in ThrottlerModule.forRoot()

    Global settings use { ttl: 60, limit: 100 } for 100 requests per 60 seconds.
  2. Step 2: Override limit on specific controller with @Throttle(60, 200)

    The decorator parameters are @Throttle(ttl, limit), so 200 requests per 60 seconds overrides global limit.
  3. Final Answer:

    Set ThrottlerModule.forRoot({ ttl: 60, limit: 100 }) globally and add @Throttle(60, 200) on the specific controller -> Option D
  4. Quick Check:

    Global config + decorator override = Set ThrottlerModule.forRoot({ ttl: 60, limit: 100 }) globally and add @Throttle(60, 200) on the specific controller [OK]
Hint: Global config in module, override with decorator on controller [OK]
Common Mistakes:
  • Swapping ttl and limit in decorator
  • Misconfiguring global module parameters
  • Trying to set global limits with decorators only
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard