The NGINX limit traffic rate module solves a common bandwidth management problem. When users download files using multi-threaded download managers, they bypass NGINX’s native limit_rate directive. They do this by opening multiple connections. The NGINX limit traffic rate module enforces a total bandwidth limit across all connections sharing the same key.
The Problem with Per-Connection Rate Limiting
NGINX’s built-in limit_rate directive limits bandwidth per connection. Consider this configuration:
location /download/ {
limit_rate 100k;
}
This limits each connection to 100 KB/s. However, a user with 10 concurrent connections consumes 1 MB/s. That’s ten times your intended limit. Download managers like aria2, wget with multiple connections, and browser extensions exploit this behavior.
This is where the NGINX limit traffic rate module becomes essential. It tracks all connections from a source and enforces a shared limit.
How the Module Works
The NGINX limit traffic rate module uses shared memory to track connections. It monitors bandwidth usage across all matching connections. When multiple connections share the same key (IP address, URL, or any variable), the module:
- Counts active connections for that key
- Divides the configured rate limit by the connection count
- Applies the calculated per-connection limit dynamically
- Adjusts in real-time as connections open and close
For example, with a 100 KB/s limit and 4 concurrent connections from the same IP, each connection receives approximately 25 KB/s. The total never exceeds your configured limit.
The module operates in NGINX’s preaccess phase. It tracks each request through the log phase for cleanup. This ensures accurate connection counting throughout the request lifecycle.
Installation
RHEL, CentOS, AlmaLinux, Rocky Linux
Install the GetPageSpeed repository and the module:
sudo dnf install https://extras.getpagespeed.com/release-latest.rpm
sudo dnf install nginx-module-limit-traffic-rate
Enable the module at the top of /etc/nginx/nginx.conf:
load_module modules/ngx_http_limit_traffic_rate_filter_module.so;
Debian and Ubuntu
First, set up the GetPageSpeed APT repository, then install:
sudo apt-get update
sudo apt-get install nginx-module-limit-traffic-rate
On Debian and Ubuntu, the package handles module loading automatically. No load_module directive is needed.
Configuration Directives
The module provides two directives for bandwidth management.
limit_traffic_rate_zone
Syntax: limit_traffic_rate_zone zone_name $variable size;
Context: http
This directive defines a shared memory zone for tracking connections. The zone stores connection state using the specified variable as the grouping key.
Parameters:
zone_name— Unique identifier for this zone$variable— Variable used to group connections (commonly$remote_addror$request_uri)size— Shared memory zone size (e.g.,32mfor 32 megabytes)
Example:
http {
# Track by client IP address
limit_traffic_rate_zone rate_by_ip $remote_addr 32m;
# Track by requested URL
limit_traffic_rate_zone rate_by_url $request_uri 32m;
}
The zone size determines tracking capacity. For IP-based tracking, 1 MB stores approximately 16,000 entries. Choose a size based on your expected concurrent unique keys.
limit_traffic_rate
Syntax: limit_traffic_rate zone_name rate;
Context: http, server, location
This directive applies the rate limit using a specified zone. All matching connections share this bandwidth limit.
Parameters:
zone_name— Name of a definedlimit_traffic_rate_zonerate— Maximum bandwidth in bytes per second (supportskandmsuffixes)
Example:
location /download/ {
limit_traffic_rate rate_by_ip 100k;
}
Practical Configuration Examples
Limit Downloads by Client IP
This is the most common use case. It prevents any single IP from consuming excessive bandwidth:
load_module modules/ngx_http_limit_traffic_rate_filter_module.so;
events {
worker_connections 1024;
}
http {
limit_traffic_rate_zone downloads_by_ip $remote_addr 32m;
sendfile on;
server {
listen 80;
server_name downloads.example.com;
root /var/www/downloads;
location / {
# 500 KB/s total across all connections per IP
limit_traffic_rate downloads_by_ip 500k;
}
}
}
Limit Downloads by File URL
For popular files receiving many concurrent downloads, limit bandwidth per file:
http {
limit_traffic_rate_zone downloads_by_file $request_uri 32m;
sendfile on;
server {
listen 80;
server_name cdn.example.com;
root /var/www/files;
location /popular/ {
# 10 MB/s total per file regardless of downloaders
limit_traffic_rate downloads_by_file 10m;
}
}
}
This ensures fair distribution when many users download the same file.
Combined IP and URL Limiting
Use multiple zones to apply different limits based on content type:
http {
limit_traffic_rate_zone per_ip $remote_addr 32m;
limit_traffic_rate_zone per_file $request_uri 32m;
sendfile on;
server {
listen 80;
root /var/www/downloads;
location /public/ {
limit_traffic_rate per_ip 200k;
}
location /premium/ {
limit_traffic_rate per_file 5m;
}
}
}
Different Limits by Content Type
Apply stricter limits to large files while allowing smaller files to transfer quickly:
http {
limit_traffic_rate_zone rate_zone $remote_addr 32m;
sendfile on;
server {
listen 80;
root /var/www;
# ISO images: strict limit
location ~ \.iso$ {
limit_traffic_rate rate_zone 100k;
}
# Video files: moderate limit
location ~ \.(mp4|mkv|avi)$ {
limit_traffic_rate rate_zone 500k;
}
# Other files: higher limit
location /files/ {
limit_traffic_rate rate_zone 1m;
}
}
}
Testing Your Configuration
After configuring the module, verify it works correctly.
Verify Syntax
nginx -t
Test Single Connection Speed
curl -w "Speed: %{speed_download} bytes/sec\n" \
-o /dev/null http://localhost/download/testfile.bin
Test Concurrent Connections
Compare bandwidth with multiple simultaneous downloads:
for i in 1 2 3 4; do
curl -s -o /dev/null http://localhost/download/testfile.bin &
done
wait
With native limit_rate, each connection gets the full limit. With limit_traffic_rate, all connections share the configured limit equally.
Comparison with Native limit_rate
Understanding the difference helps you choose the right approach.
| Feature | Native limit_rate |
limit_traffic_rate |
|---|---|---|
| Scope | Per connection | Total across connections |
| Multi-connection downloads | Each gets full rate | Bandwidth shared |
| Use case | Simple throttling | Preventing abuse |
| Shared memory | Not required | Required |
Example with 100 KB/s Limit and 4 Connections
Native limit_rate:
– Each connection: 100 KB/s
– Total bandwidth consumed: 400 KB/s
limit_traffic_rate module:
– Each connection: ~25 KB/s
– Total bandwidth consumed: 100 KB/s
The difference is significant for bandwidth planning. Choose based on your requirements.
Performance Considerations
Shared Memory Sizing
Zone size affects how many unique keys you can track simultaneously:
- 1 MB: ~16,000 entries
- 10 MB: ~160,000 entries
- 32 MB: ~500,000 entries
If the zone fills up, new connections receive 503 Service Unavailable errors. Monitor your traffic and size the zone accordingly.
Sendfile Optimization
The module works best with sendfile on enabled:
http {
sendfile on;
sendfile_max_chunk 512k;
}
Sendfile allows efficient kernel-level file transfers. The module adjusts sendfile_max_chunk to enforce rate limits.
CPU Overhead
The module adds minimal CPU overhead. It performs hash lookups and shared memory operations. For most deployments, the overhead is negligible.
Troubleshooting
Rate Limit Not Applied
First, verify the module is loaded:
nginx -T 2>&1 | grep limit_traffic_rate_zone
Ensure sendfile on is set in your configuration. The module relies on sendfile for throttling.
503 Errors Under Load
The shared memory zone may be full. Increase the zone size:
limit_traffic_rate_zone rate_zone $remote_addr 64m;
Monitor zone usage during peak traffic periods.
Inconsistent Speeds at High Rates
For very small files or fast local connections, the throttling algorithm may show variations. The module is most effective for larger file transfers. The rate limiting stabilizes after the initial data burst.
Security Best Practices
Combine with Connection Limits
Use alongside NGINX’s native limit_conn directive for comprehensive protection:
http {
limit_conn_zone $remote_addr zone=conn_limit:10m;
limit_traffic_rate_zone rate_limit $remote_addr 32m;
server {
location /download/ {
limit_conn conn_limit 10;
limit_traffic_rate rate_limit 500k;
}
}
}
This limits both connection count and total bandwidth per IP.
Protect Against Zone Exhaustion
Set appropriate zone sizes. Consider using limit_conn to prevent attackers from exhausting shared memory.
Monitor Bandwidth Usage
Track downloads through NGINX logging:
log_format downloads '$remote_addr - $request_uri - $bytes_sent - $request_time';
access_log /var/log/nginx/downloads.log downloads;
This helps identify abuse patterns and tune your limits.
Common Use Cases
The NGINX limit traffic rate module is ideal for several scenarios:
- File hosting services — Fair bandwidth distribution among users
- Software distribution mirrors — Prevent single users from monopolizing bandwidth
- Media streaming platforms — Control bandwidth per viewer or content piece
- API rate limiting — Limit data transfer rates for large responses
- Freemium download services — Enforce bandwidth tiers for free users
- CDN origin servers — Prevent origin overload from aggressive edge nodes
Related Modules
For comprehensive traffic management, consider these related modules:
- NGINX Rate Limiting — Limit requests per second
- NGINX Dynamic Limit Req Module — Dynamic request rate limiting
Conclusion
The NGINX limit traffic rate module provides bandwidth management beyond native limit_rate. By enforcing total limits across all connections from the same source, it prevents users from bypassing rate limits with download managers.
For file hosting and content delivery, this module ensures fair bandwidth distribution. It protects your server resources from abuse while maintaining service quality.
The module source is on GitHub. RPM packages are at the GetPageSpeed module page. Debian/Ubuntu packages are at the APT repository.

