Rate Limiting
Protect your tunnels from abuse and DoS attacks with request throttling
Overview
Rate Limiting policies control how many requests clients can make to your tunnel within a time window. Essential for API protection, preventing abuse, and ensuring fair resource usage.
Key Features
- • Per-IP rate limits
- • Global rate limits (all IPs combined)
- • Configurable time windows (second/minute/hour)
- • Burst allowance support
- • Custom response codes (429 or 503)
Configuration Schema
| Field | Type | Description |
|---|---|---|
| requests_per_minute | Number (required) | Maximum number of requests allowed per minute. This is the base rate limit. |
| burst | Number (optional) | Maximum burst size - extra requests allowed beyond the rate limit. Defaults to 2x requests_per_minute if not specified. |
| scope | String (optional) | How to apply the rate limit:
|
How It Works
- • Rate limiting uses a token bucket algorithm - requests consume tokens, tokens refill at the specified rate
- • Burst allows temporary spikes above the base rate (useful for handling traffic bursts)
- • When the limit is exceeded, requests are blocked with a 429 Too Many Requests response
- • Limits are tracked separately based on the
scopesetting - • Rate limits are applied per minute (converted internally to requests per second)
Configuration Examples
Example 1: Standard API Rate Limit
{
"name": "Standard API Limits",
"per_ip_limit": {
"requests": 100,
"window": "minute",
"burst": 20
},
"response_code": 429,
"retry_after": 60
}Each IP can make 100 requests per minute, with a burst of 120.
Example 2: Strict DoS Protection
{
"name": "DoS Protection",
"per_ip_limit": {
"requests": 10,
"window": "second",
"burst": 0
},
"response_code": 503,
"retry_after": 1
}Very strict: 10 requests per second per IP, no burst allowed.
Example 3: Global Traffic Limiter
{
"name": "Global Traffic Cap",
"global_limit": {
"requests": 10000,
"window": "hour"
},
"response_code": 503,
"retry_after": 3600
}Cap total traffic at 10,000 requests per hour across all users.
Example 4: Generous Limits for Development
{
"name": "Development Limits",
"per_ip_limit": {
"requests": 1000,
"window": "minute",
"burst": 100
},
"response_code": 429,
"retry_after": 10
}Generous limits for testing: 1000/min + 100 burst.
Example 5: Combined IP + Global Limits
{
"name": "Balanced Protection",
"per_ip_limit": {
"requests": 60,
"window": "minute"
},
"global_limit": {
"requests": 5000,
"window": "minute"
},
"response_code": 429,
"retry_after": 60
}60/min per IP, 5000/min globally (protects both individual abuse and total load).
Response Headers
When rate limiting is active, NGSRV includes standard rate limit headers:
HTTP/1.1 429 Too Many Requests X-RateLimit-Limit: 100 X-RateLimit-Remaining: 0 X-RateLimit-Reset: 1614556860 Retry-After: 60
| Header | Description |
|---|---|
| X-RateLimit-Limit | Total requests allowed in window |
| X-RateLimit-Remaining | Requests remaining in current window |
| X-RateLimit-Reset | Unix timestamp when limit resets |
| Retry-After | Seconds until requests allowed again |
Common Use Cases
API Protection
Prevent API abuse and ensure fair usage among clients.
DoS Prevention
Protect against denial-of-service attacks and traffic spikes.
Resource Management
Control backend load by limiting incoming request rate.
Cost Control
Prevent unexpected costs from runaway API usage.
Scraper Protection
Block aggressive scrapers and bots with strict per-IP limits.
How to Use
Step 1: Create Policy
Go to Dashboard → Security → Rate Limiting
- Click "Create Policy"
- Enter policy name and description
- Configure per-IP limits (requests/window/burst)
- Optionally configure global limits
- Choose response code (429 or 503)
- Save the policy
Step 2: Apply to Tunnel
ngsrv http 3000 --policy ngsrv_rate_ABC123Step 3: Test Rate Limits
# Test with curl in a loop
for i in {1..150}; do curl -w "\n" https://myapp.tnl.ngsrv.com; doneYou should see 429 responses after exceeding the limit.
Best Practices
✅ Start Conservative
Begin with stricter limits and relax them based on real usage patterns.
✅ Use 429 Status Code
429 is the standard HTTP status for rate limiting, most clients handle it correctly.
✅ Allow Reasonable Bursts
Burst allowance handles legitimate traffic spikes gracefully.
⚠️ Monitor and Adjust
Check audit logs regularly to ensure limits aren't blocking legitimate users.
💡 Combine with WAF
Use rate limiting together with WAF rules for comprehensive protection.