Site icon GetPageSpeed

NGINX Limit Traffic Rate Module Guide

NGINX Limit Traffic Rate Module: Control Total Bandwidth Across Multiple Connections

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:

  1. Counts active connections for that key
  2. Divides the configured rate limit by the connection count
  3. Applies the calculated per-connection limit dynamically
  4. 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:

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:

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:

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:

For comprehensive traffic management, consider these related modules:

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.

D

Danila Vershinin

Founder & Lead Engineer

NGINX configuration and optimizationLinux system administrationWeb performance engineering

10+ years NGINX experience • Maintainer of GetPageSpeed RPM repository • Contributor to open-source NGINX modules

Exit mobile version