NGINX limit_rate directive: Explained with examples

Updated: January 19, 2024 By: Guest Contributor Post a comment

Introduction

NGINX is a powerful web server known for its high performance and low memory footprint. One of the useful features it offers is rate limiting, which helps control the speed at which responses are sent to the client. The limit_rate directive is at the core of this functionality. In this tutorial, we delve into the limit_rate directive, providing practical code examples and explaining how it works in different scenarios.

Basics of limit_rate Directive

The limit_rate directive in NGINX can control the rate of response data that is sent to clients. This can help manage bandwidth usage and ensure a fair distribution of resources among users. The directive can be set globally, per server, or location.

http {
    limit_rate 10k;
}

This basic configuration sets a global rate limit of 10 kilobytes per second for each client. You can also set limit_rate within a server or location block:

server {
    location /downloads/ {
        limit_rate 5k;
    }
}

This limits the rate to 5 kilobytes per second for responses served from the /downloads/ directory.

Dynamic Rate Limiting

You can set the limit_rate dynamically based on variables. For example, you may want to set a different rate limit for different user agents.

http {
    map $http_user_agent $rate {
        default        10k;
        ~*Googlebot    20k;
        ~*Bingbot      5k;
    }

    server {
        location / {
            limit_rate $rate;
        }
    }
}

The map block maps user agents to specific rate limits. This allows you to customize the response rate based on the client’s user agent.

Conditional Rate Limiting

NGINX also allows you to apply rate limiting conditionally. Use the if directive to set the limit_rate only when certain conditions are true.

server {
    if ($cookie_user == "premium") {
        set $limit_rate 0;
    }

    location / {
        limit_rate $limit_rate;
    }
}

In this example, premium users aren’t subjected to rate limiting. This is achieved by setting the $limit_rate variable to 0 if a particular cookie is present, bypassing the limit.

Rate Limiting and Buffering

NGINX buffers responses before sending them out, but sometimes you might want to disable buffering along with setting a rate limit.

location /stream/ {
    limit_rate 50k;
    proxy_buffering off;
}

This location block sends out streams at a maximum of 50 kilobytes per second and disables proxy buffering to have a smooth streaming experience.

Advanced Rate Limiting with limit_conn_module

For more advanced rate limiting, you might need to use the limit_conn_module along with the limit_rate directive to limit the number of connections each user can open.

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

    server {
        location /download/ {
            limit_conn addr 1;
            limit_rate 100k;
        }
    }
}

This sets up a zone called ‘addr’ that tracks connections based on the client’s IP address and limits each IP to a single connection, with a rate limit of 100 kilobytes per second for downloads.

Limiting Rate Based on Arguments

The limit_rate directive can also vary based on arguments within the request URL.

map $arg_rate $rate_custom {
    ~^[0-9]+ $arg_rate;
    default    1k;
}

server {
    location / {
        limit_rate $rate_custom;
    }
}

This map uses a regular expression to check if the “rate” argument in the URL is a number and applies rate limiting based on its value. This can be useful for dynamically controlling rate limits through API or special links.

Conclusion

The limit_rate directive is a versatile tool in NGINX’s arsenal, providing granular control over how data is transmitted to clients. Whether you need to manage server loads, optimize the user experience, or dynamically adjust your resource allocation, the concepts and examples in this tutorial can help you implement practical rate limiting strategies for your web applications.