How to Configure Rate Limiting with Short, Medium, and Long TTL Limits in OpenWA
Configure short-, medium-, and long-TTL rate limiting in OpenWA by setting the RATE_LIMIT_SHORT_TTL, RATE_LIMIT_MEDIUM_TTL, and RATE_LIMIT_LONG_TTL environment variables, which override the defaults defined in src/config/configuration.ts and are consumed by the NestJS Throttler module in src/app.module.ts.
OpenWA implements a three-tier rate limiting strategy using NestJS Throttler to protect the WhatsApp API from abuse. This architecture allows you to define distinct time-to-live (TTL) windows and request limits for short-term bursts, medium-term sustained traffic, and long-term aggregate usage, all configurable via environment variables without modifying source code.
Understanding the Three-Tier Rate Limiting Architecture
OpenWA’s rate limiting system relies on three interconnected components: the central configuration file, security middleware constants, and the Throttler module registration.
Configuration Defaults in configuration.ts
The primary source of truth for rate limiting values resides in src/config/configuration.ts. Lines 66–76 define the api.rateLimit object, mapping environment variables to default values for all three tiers.
| Tier | Environment Variable (TTL) | Environment Variable (Limit) | Default TTL | Default Limit |
|---|---|---|---|---|
| Short | RATE_LIMIT_SHORT_TTL |
RATE_LIMIT_SHORT_LIMIT |
1000 ms | 10 requests |
| Medium | RATE_LIMIT_MEDIUM_TTL |
RATE_LIMIT_MEDIUM_LIMIT |
60000 ms | 100 requests |
| Long | RATE_LIMIT_LONG_TTL |
RATE_LIMIT_LONG_LIMIT |
3600000 ms | 1000 requests |
Source: [src/config/configuration.ts](https://github.com/rmyndharis/OpenWA/blob/main/src/config/configuration.ts#L66-L76)
Security Constants Fallback
src/common/security/security.middleware.ts contains a fallback SecurityConfig.rateLimit object (lines 81–86) that mirrors the same default values. This ensures that if the configuration service fails to load, the application still maintains protective rate limiting boundaries.
Source: [src/common/security/security.middleware.ts](https://github.com/rmyndharis/OpenWA/blob/main/src/common/security/security.middleware.ts#L81-L86)
Module Registration in app.module.ts
The values are injected into the application through ThrottlerModule.forRootAsync in src/app.module.ts (lines 120–131). The factory function retrieves the TTL and limit values for each tier using ConfigService.get<number>() and registers three separate throttler instances.
Source: [src/app.module.ts](https://github.com/rmyndharis/OpenWA/blob/main/src/app.module.ts#L120-L131)
How to Configure Rate Limiting via Environment Variables
All rate limiting parameters are configurable at runtime through environment variables. Create or modify your .env file in the project root to override the defaults.
# Short-term burst protection (10 requests per second)
RATE_LIMIT_SHORT_TTL=1000
RATE_LIMIT_SHORT_LIMIT=10
# Medium-term protection (100 requests per minute)
RATE_LIMIT_MEDIUM_TTL=60000
RATE_LIMIT_MEDIUM_LIMIT=100
# Long-term protection (1000 requests per hour)
RATE_LIMIT_LONG_TTL=3600000
RATE_LIMIT_LONG_LIMIT=1000
After updating the environment variables, restart the OpenWA container or the Node.js process for the changes to take effect. The configuration is read once at startup and propagated through NestJS’s dependency injection system.
Implementation Details and Code Examples
How the Values Flow Through the Application
- Startup:
ConfigModuleloadsconfiguration.tsand parses environment variables into theapi.rateLimitnamespace. - Registration:
ThrottlerModule.forRootAsyncextracts the six values (three TTLs and three limits) usingconfigService.get<number>(). - Enforcement: The throttler middleware applies the most restrictive limit that applies to the current request window.
- Headers: As implemented in
src/main.ts, responses includeX-RateLimit-Limit,X-RateLimit-Remaining, andX-RateLimit-Resetheaders.
Example: Aggressive Short-Term Limits
To restrict short-term bursts to 5 requests per 2 seconds while keeping other tiers standard:
# .env
RATE_LIMIT_SHORT_TTL=2000
RATE_LIMIT_SHORT_LIMIT=5
RATE_LIMIT_MEDIUM_TTL=60000
RATE_LIMIT_MEDIUM_LIMIT=100
RATE_LIMIT_LONG_TTL=3600000
RATE_LIMIT_LONG_LIMIT=1000
Verify the headers with a test request:
curl -i http://localhost:2785/api/v1/health
Expected response headers:
X-RateLimit-Limit: 5
X-RateLimit-Remaining: 4
X-RateLimit-Reset: 2
Example: Per-Route Override with @Throttle
For specific controllers requiring different limits, use the @Throttle decorator from @nestjs/throttler to override the global configuration:
import { Controller, Get } from '@nestjs/common';
import { Throttle } from '@nestjs/throttler';
@Controller('webhook')
export class WebhookController {
// Allow only 2 requests per minute for this endpoint
@Get('validate')
@Throttle(60, 2) // ttl: 60 seconds, limit: 2 requests
validateWebhook() {
return { status: 'valid' };
}
}
Example: Runtime Configuration Debugging
To verify the active rate limiting configuration programmatically:
import { ConfigService } from '@nestjs/config';
import { Injectable, Logger } from '@nestjs/common';
@Injectable()
export class RateLimitDebugService {
constructor(private readonly configService: ConfigService) {}
logLimits() {
const shortTtl = this.configService.get<number>('api.rateLimit.shortTtl');
const shortLimit = this.configService.get<number>('api.rateLimit.shortLimit');
const mediumTtl = this.configService.get<number>('api.rateLimit.mediumTtl');
const mediumLimit = this.configService.get<number>('api.rateLimit.mediumLimit');
const longTtl = this.configService.get<number>('api.rateLimit.longTtl');
const longLimit = this.configService.get<number>('api.rateLimit.longLimit');
Logger.log(`Rate Limits - Short: ${shortLimit}req/${shortTtl}ms`);
Logger.log(`Rate Limits - Medium: ${mediumLimit}req/${mediumTtl}ms`);
Logger.log(`Rate Limits - Long: ${longLimit}req/${longTtl}ms`);
}
}
Summary
- OpenWA implements three-tier rate limiting (short, medium, long) via NestJS Throttler, configured through the
ConfigService. - Default values are defined in
src/config/configuration.ts(lines 66–76) and mirrored insrc/common/security/security.middleware.ts(lines 81–86). - Override defaults by setting
RATE_LIMIT_SHORT_TTL,RATE_LIMIT_MEDIUM_TTL, andRATE_LIMIT_LONG_TTLenvironment variables with their corresponding*_LIMITvalues. - The throttler is registered in
src/app.module.ts(lines 120–131) usingThrottlerModule.forRootAsync. - Use the
@Throttledecorator to override global limits for specific routes. - Changes require an application restart to take effect.
Frequently Asked Questions
What are the default rate limiting values in OpenWA?
By default, OpenWA enforces three tiers: short (10 requests per 1000ms), medium (100 requests per 60000ms), and long (1000 requests per 3600000ms). These defaults are hardcoded in src/config/configuration.ts and serve as fallbacks if environment variables are not set.
How do I apply different rate limits to specific API endpoints?
Apply the @Throttle(ttl, limit) decorator to individual controller methods. This overrides the global configuration for that specific route. For example, @Throttle(60, 2) restricts the endpoint to 2 requests per minute regardless of the global short, medium, or long settings.
Where can I see the current rate limit status for my requests?
OpenWA includes X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers in HTTP responses. These headers indicate the current tier’s maximum requests, remaining quota, and seconds until the limit resets, respectively.
Do I need to restart OpenWA after changing rate limit environment variables?
Yes. OpenWA reads the configuration once at startup. After modifying .env or your container’s environment variables, you must restart the application process or container for the new TTL and limit values to take effect.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →