Rate Limiting Configuration
NestLens includes built-in rate limiting to protect the dashboard and API endpoints from abuse and excessive requests. This ensures stable performance and prevents resource exhaustion.
:::info Disabled by default
Rate limiting is off by default — NestLens is a development/debugging tool. rateLimit defaults to false. Provide a RateLimitConfig object to turn it on (recommended when the dashboard is exposed beyond localhost). Set it back to false to disable it explicitly.
:::
RateLimitConfig Interface
The rate limiting configuration provides controls for managing request rates:
interface RateLimitConfig {
windowMs?: number; // Time window in milliseconds
maxRequests?: number; // Maximum requests per window per IP
}
Configuration Options
windowMs
Defines the time window (in milliseconds) for tracking request rates.
- Type:
number - Default:
60000(1 minute)
NestLensModule.forRoot({
rateLimit: {
windowMs: 60000, // 1 minute window
},
});
Common time windows:
// 30 seconds
NestLensModule.forRoot({
rateLimit: {
windowMs: 30 * 1000,
},
});
// 1 minute (default)
NestLensModule.forRoot({
rateLimit: {
windowMs: 60 * 1000,
},
});
// 5 minutes
NestLensModule.forRoot({
rateLimit: {
windowMs: 5 * 60 * 1000,
},
});
// 15 minutes
NestLensModule.forRoot({
rateLimit: {
windowMs: 15 * 60 * 1000,
},
});
maxRequests
Sets the maximum number of requests allowed per IP address within the time window.
- Type:
number - Default:
100
NestLensModule.forRoot({
rateLimit: {
maxRequests: 100, // 100 requests per window
},
});
Adjust based on your needs:
// Restrictive (for production)
NestLensModule.forRoot({
rateLimit: {
windowMs: 60000, // 1 minute
maxRequests: 50, // 50 requests/minute
},
});
// Moderate (default)
NestLensModule.forRoot({
rateLimit: {
windowMs: 60000, // 1 minute
maxRequests: 100, // 100 requests/minute
},
});
// Permissive (for development)
NestLensModule.forRoot({
rateLimit: {
windowMs: 60000, // 1 minute
maxRequests: 500, // 500 requests/minute
},
});
// Very restrictive (public access)
NestLensModule.forRoot({
rateLimit: {
windowMs: 60000, // 1 minute
maxRequests: 20, // 20 requests/minute
},
});
Disabling Rate Limiting
You can completely disable rate limiting by setting rateLimit to false:
NestLensModule.forRoot({
rateLimit: false, // No rate limiting
});
When to Disable
Consider disabling rate limiting in these scenarios:
- Development environment: No need for limits during development
- Internal network: When behind a trusted firewall
- Custom rate limiting: Using your own rate limiting middleware
- Load testing: Testing dashboard performance
// Disable in development only
NestLensModule.forRoot({
rateLimit: process.env.NODE_ENV === 'development'
? false
: { windowMs: 60000, maxRequests: 100 },
});
Per-IP Tracking
Rate limiting is enforced on a per-IP address basis. Each unique IP address gets its own independent rate limit counter.
How It Works
- IP Extraction: The client's IP address is extracted from the request
- Counter Tracking: A counter is maintained for each IP address
- Window Reset: Counters reset after the configured
windowMsperiod - Limit Enforcement: Requests exceeding
maxRequestsare rejected with 429 status
// Example: 100 requests per minute per IP
NestLensModule.forRoot({
rateLimit: {
windowMs: 60000,
maxRequests: 100,
},
});
// Result:
// - IP 192.168.1.1 can make 100 requests/minute
// - IP 192.168.1.2 can make 100 requests/minute (independent counter)
// - IP 10.0.0.1 can make 100 requests/minute (independent counter)
IP Address Detection
NestLens correctly identifies client IPs even behind proxies:
- Checks
X-Forwarded-Forheader (when behind reverse proxy) - Falls back to
req.ip(direct connection) - Uses the leftmost IP in
X-Forwarded-Forchain
Rate Limit Response
When a client exceeds the rate limit, they receive:
HTTP Status: 429 Too Many Requests
Response Headers: Retry-After: 60
Response Body — the same envelope every NestLens endpoint answers with:
{
"success": false,
"data": null,
"error": {
"code": "ERR_RATE_LIMITED",
"message": "Too many requests. Please try again later.",
"details": { "retryAfter": 60 }
},
"meta": { "timestamp": "2026-01-01T00:00:00.000Z", "duration": 0 }
}
retryAfter is how many seconds until the limit resets. It is in the
Retry-After header as well, which is what a generic HTTP client will look
at.
Configuration Examples
Development Environment
No rate limiting for unrestricted development:
NestLensModule.forRoot({
rateLimit: false,
});
Or very permissive limits:
NestLensModule.forRoot({
rateLimit: {
windowMs: 60000,
maxRequests: 1000, // Very high limit
},
});
Production Environment
Balanced protection while allowing normal usage:
NestLensModule.forRoot({
rateLimit: {
windowMs: 60000, // 1 minute
maxRequests: 100, // 100 requests/minute
},
});
High-Security Environment
Strict limits for sensitive environments:
NestLensModule.forRoot({
rateLimit: {
windowMs: 60000, // 1 minute
maxRequests: 30, // 30 requests/minute
},
});
API-Heavy Dashboard
Higher limits for dashboards with frequent polling:
NestLensModule.forRoot({
rateLimit: {
windowMs: 60000, // 1 minute
maxRequests: 300, // 300 requests/minute
},
});
Shared Development Environment
Prevent one developer from monopolizing resources:
NestLensModule.forRoot({
rateLimit: {
windowMs: 60000, // 1 minute
maxRequests: 200, // 200 requests/minute per developer
},
});
Environment-Specific Configuration
const rateLimitConfig = {
development: false, // No limits in development
test: false, // No limits in tests
staging: {
windowMs: 60000,
maxRequests: 200, // Permissive for testing
},
production: {
windowMs: 60000,
maxRequests: 100, // Standard production limits
},
};
NestLensModule.forRoot({
rateLimit: rateLimitConfig[process.env.NODE_ENV] || rateLimitConfig.production,
});
Best Practices
1. Match Limits to Dashboard Usage
Consider typical dashboard usage patterns:
// Calculate based on polling frequency
const dashboardPollingIntervalSeconds = 5;
const safetyMultiplier = 3; // Allow 3x polling rate
const requestsPerMinute = (60 / dashboardPollingIntervalSeconds) * safetyMultiplier;
NestLensModule.forRoot({
rateLimit: {
windowMs: 60000,
maxRequests: requestsPerMinute, // e.g., 36 for 5s polling
},
});
2. Consider Multiple Users
Adjust limits if multiple users share the same IP:
// Office with shared IP
NestLensModule.forRoot({
rateLimit: {
windowMs: 60000,
maxRequests: 500, // Higher to accommodate multiple users
},
});
// Individual users
NestLensModule.forRoot({
rateLimit: {
windowMs: 60000,
maxRequests: 100, // Lower for individual access
},
});
3. Monitor Rate Limit Hits
Log when rate limits are triggered:
// In your application
app.use((req, res, next) => {
res.on('finish', () => {
if (res.statusCode === 429) {
logger.warn(`Rate limit exceeded for IP: ${req.ip}`);
}
});
next();
});
4. Coordinate with Authorization
Combine with authorization for better security:
NestLensModule.forRoot({
// Strict rate limiting
rateLimit: {
windowMs: 60000,
maxRequests: 50,
},
// Plus IP whitelist
authorization: {
allowedIps: ['10.0.1.*'],
},
});
5. Progressive Limits by Environment
Gradually tighten limits as you move to production:
const limits = {
development: false,
test: false,
staging: { windowMs: 60000, maxRequests: 200 },
production: { windowMs: 60000, maxRequests: 100 },
};
NestLensModule.forRoot({
rateLimit: limits[process.env.NODE_ENV],
});
Troubleshooting
Users Hitting Rate Limits Frequently
If legitimate users are being rate-limited:
- Increase maxRequests: Allow more requests per window
NestLensModule.forRoot({
rateLimit: {
maxRequests: 200, // Increased from 100
},
});
- Increase windowMs: Use a longer time window
NestLensModule.forRoot({
rateLimit: {
windowMs: 120000, // 2 minutes instead of 1
maxRequests: 100,
},
});
- Check dashboard polling: Reduce auto-refresh frequency
Rate Limiting Not Working
If rate limiting appears ineffective:
- Verify configuration: Ensure
rateLimitis notfalse - Check proxy configuration: Ensure IP detection works correctly
- Test directly: Try from different IPs to verify per-IP tracking
Behind Multiple Proxies
If behind multiple reverse proxies:
- Trust proxy setting: Tell your HTTP adapter to trust proxy headers so the real client IP is used.
// Express (main.ts)
app.set('trust proxy', true);
// Fastify (main.ts) — pass it to the adapter
const app = await NestFactory.create<NestFastifyApplication>(
AppModule,
new FastifyAdapter({ trustProxy: true }),
);
- Verify X-Forwarded-For: Check that the header contains the real client IP
Performance Impact
Rate limiting has minimal performance impact:
- Memory: Small in-memory counter per IP address
- CPU: Simple counter increments
- Storage: No database operations
For most applications, rate limiting overhead is negligible.
Next Steps
- Authorization Configuration - Secure dashboard access
- Basic Configuration - General NestLens settings
- Pruning Configuration - Data cleanup settings