limit download speed in nginx

How to Limit Download Speed in NGINX

Last updated on July 23rd, 2024 at 06:11 am

NGINX is a popular web server used by many high traffic websites and applications. It provides numerous features to easily handle a large number of concurrent users. Nevertheless, it is important to limit HTTP bandwidth on your website to prevent a few users from cornering all your downloads and ensure that all users have good user experience. It also protects your site from malicious attacks such as Brute force and DDOS attacks. In this article, we will look at how to limit download speed in NGINX, which in turn limits HTTP bandwidth. As a result, each user will be able to download content at a maximum download speed that we define.

What is Rate Limiting in NGINX

NGINX allows various method to limit the number of HTTP requests users are allowed to make. In all cases, it uses a leaky bucket algorithm, also known as FIFO (First In First Out) queue. Here NGINX enqueues all requests it receives and processes them sequentially to avoid getting overwhelmed. There are several ways you can control how the queue is filled. For example, NGINX allows you to limit no. of connections, request rate, and network bandwidth. For each of these controls, it provides a distinct server directive that directly controls these parameters, and thereby the rate of processing.

How to Limit Download Speed in NGINX

Here is how to limit download speed in NGINX. We will use limit_rate directive to limit download speed in NGINX. We have assumed that you have already installed NGINX on your server. Here are the steps to install NGINX.

1. Limit Number of Connections

The simplest way to limit download speed or rate of processing is to control the number of concurrent connections allowed at any given point of time.

You can use limit_conn directive to easily limit the number of connections to a given server resource, within location, server or http context.

Here is an example to use limit_conn to limit number of connections to 10 for a given URL.

http {

# ...

limit_conn my_url 10;

# ...

}

Thereafter, when you define the location for above URL, NGINX will automatically limit number of connections.

location /my_url/ {
proxy_pass http://your_backend;
}

In this case, the requests to /my_url will be proxied to your_backend and it will be limited to 10. This approach can be used to limit number of connections to any resource on your server, not just URL. For example, it is very effective to limit number of connections to images and documents.

2. Limit HTTP bandwidth

limit_rate directive allows you to limit download speed in NGINX. You can add it in http, location or server blocks

Here’s an example to limit download speed to 50kb/sec.

limit_rate 50k;

Here’s how you to add it to http block and apply the limit to all servers.

http {
   ...
   limit 50k;
   ...
}

Bonus Read : How to Remove Trailing Slash in NGINX

Here’s how to limit http bandwidth for a specific server and all its URLs

server {
   server_name www.example.com;
   listen 80;
   ...
   limit_rate 50k;
   ...
}

Here’s how to limit download speed for specific location, e.g /downloads/

location /downloads/ {
   ...
   limit rate 50k;
   ...
}

The above configuration tells NGINX to limit download speed per connection.

Bonus Read : How to Enable NGINX Gzip Compression

However, if users create multiple connections, they can get more bandwidth. So we will use limit_conn_zone directive in http block to limit total amount of shared memory available for managing connections.

https{
...
limit_conn_zone $binary_remote_addr zone=addr:10m;
...
}

Once the allotted memory is exhausted for a connection, NGINX will close the connection.

Similarly, we also add the following line in location block to limit 1 connection per IP address.

limit_conn addr 1;

Bonus Read : How to Enable Leverage Browser Caching in NGINX

Based on our above learnings, here’s a sample configuration that you can use to limit download speed in NGINX.

http {
   limit_conn_zone $binary_remote_addr zone=addr:10m;
   ...

   server {
      ...
      location /downloads/ {
         ...
         limit rate 50k;
         ...
      }
      ...
   }
...
}

3. Limit Request Rate

In this case, we can limit the number of requests processed by NGINX using limit_req_zone and limit_req directives. limit_req_zone allows you to specify the max amount of shared memory to be utilized for a given memory zone. It needs to be specified in http context. Here is its syntax.

http {
...
limit_req_zone key zone rate;
...
}

In the above command, the key is the server variable used to uniquely identify each client, zone is the name and space definition of memory zone, and rate is the rate of request. Here is an example to create a shared memory zone called abc with a space of 10Mb, where each client is differentiated using their IP address stored in $binary_remote_addr server variable. The rate of request is limited to 1 request per second per client.

http {
#...
limit_req_zone $binary_remote_addr zone=abc:10m rate=1r/s;
}

Once you have defined the shared memory zone, you can use it with limit_req directive in location, server or http context. Here is an example to apply the zone abc to my_url within location block.

http {
...

limit_req_zone $binary_remote_addr zone=abc:10m rate=1r/s;

server {
...

location /my_url/ {
limit_req zone=abc;
}
}
}

In the above case, when the number of requests exceeds the size of shared memory, NGINX will respond with 503 Service Unavailable. In this case, you can buffer and process these excessive requests by specifying the burst parameter that specifies the max number of extra requests that are put in an additional queue.

http {
...

limit_req_zone $binary_remote_addr zone=abc:10m rate=1r/s;

server {
...

location /my_url/ {
limit_req zone=abc burst=10;
}
}
}

In the above case, if the request rate is more than 1 request/sec, it is put in shared memory zone abc. If it is even more than that, then it is put into a buffer with length 10. If there are even more requests, then only they will be rejected with 503 error response.

In this case, the overall rate of processing request will still be limited to 1 request/second and the extra requests will need to wait. If you do not want them to face any delay, use nodelay keyword as shown below.

location /my_url/ {
limit_req zone=abc burst=10 nodelay;
}

In this case, all the extra requests will be processes immediately even if the rate of processing requests is more than 1 request/second as specified by us in limit_req_zone directive.

Conclusion

In this article, we have learnt how to limit download speed in NGINX. You can do so by controlling the number of incoming connections, requests or request rate. Depending on your requirements, you can use any of the above methods to quickly limit the requests processed by your NGINX server and regulate server load.

Ubiq makes it easy to visualize data, and monitor them in real-time dashboards. Try Ubiq for free.