Master Nginx Rate Limiting: From Basics to Advanced Configurations

This guide explains how Nginx's rate‑limiting works, covering the leaky‑bucket algorithm, basic directives, burst and nodelay options, whitelist handling, logging, custom error codes, and advanced configuration examples for securing and optimizing HTTP request traffic.

21CTO
21CTO
21CTO
Master Nginx Rate Limiting: From Basics to Advanced Configurations

Nginx provides a powerful rate‑limiting feature that can control the number of HTTP requests (GET or POST) a client can make within a specific time window, helping mitigate brute‑force attacks, web crawlers, and DDoS attempts.

Nginx Rate Limiting How It Works

The mechanism uses the leaky‑bucket algorithm, visualized as water poured into a bucket that leaks at a constant rate; if the inflow exceeds the leak rate, excess water overflows, analogous to request drops.

Leaky bucket diagram
Leaky bucket diagram

In request handling, the water represents client requests, the bucket acts as a FIFO queue, leaked water denotes processed requests, and overflowed water indicates dropped requests.

Basic Rate‑Limiting Configuration

The two main directives are limit_req_zone and limit_req:

limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
server {
    location /login/ {
        limit_req zone=mylimit;
        proxy_pass http://my_upstream;
    }
}
limit_req_zone

defines the shared memory zone, key, and rate. The key (e.g., $binary_remote_addr) identifies a client IP in binary form, saving memory compared to the string representation.

The zone stores per‑IP state in shared memory, allowing multiple worker processes to share the limits. Approximately 16,000 IP states fit in 1 MB; when the zone fills, the oldest entries are evicted.

If the zone runs out of space, Nginx returns a 503 status. To prevent memory exhaustion, Nginx may delete up to two entries that have been idle for 60 seconds.

The rate parameter sets the maximum request rate (e.g., 10 requests per second, which Nginx tracks with millisecond granularity, effectively 1 request per 100 ms).

To enforce the limit, include the limit_req directive in a specific location or server block.

Handling Bursts and Concurrency

When multiple requests arrive within 100 ms, the second request would receive a 503. To allow short bursts, use the burst parameter:

location /login/ {
    limit_req zone=mylimit burst=20;
    proxy_pass http://my_upstream;
}
burst

defines how many excess requests can be queued (e.g., 20). Requests beyond the burst limit are rejected with 503.

Adding nodelay processes burst requests immediately without waiting for the leaky‑bucket timer, while still respecting the overall rate limit:

location /login/ {
    limit_req zone=mylimit burst=20 nodelay;
    proxy_pass http://my_upstream;
}

With nodelay, if 21 requests arrive simultaneously, Nginx forwards all 21, marks 20 slots as occupied, and releases one slot every 100 ms.

Advanced Configuration Examples

Combining rate limiting with other Nginx features enables fine‑grained control, such as whitelisting certain IP ranges:

geo $limit {
    default 1;
    10.0.0.0/8 0;
    192.168.0.0/24 0;
}
map $limit $limit_key {
    0 "";
    1 $binary_remote_addr;
}
limit_req_zone $limit_key zone=req_zone:10m rate=5r/s;
server {
    location / {
        limit_req zone=req_zone burst=10 nodelay;
        # ...
    }
}

IP addresses in the whitelisted subnets receive an empty key, so the rate limit does not apply to them, while all other IPs are limited to 5 requests per second.

You can also place multiple limit_req directives in a single location; the most restrictive limit wins.

Logging and Error Handling

By default, Nginx logs delayed or dropped requests at the error level:

2017/06/13 04:20:00 [error] 120315#0: *32086 limiting requests, excess: 1.000 by zone "mylimit", client: 192.168.1.2, server: Nginx.com, request: "GET / HTTP/1.0", host: "Nginx.com"

Use limit_req_log_level to change the log level, e.g., to warn for rejected requests.

Clients exceeding the limit receive a 503 status by default; you can customize the response code with limit_req_status (e.g., 444):

location /login/ {
    limit_req zone=mylimit burst=20 nodelay;
    limit_req_status 444;
}

To block all requests to a specific URL, use the deny all directive:

location /assets/header.php {
    deny all;
}

Conclusion

We have covered Nginx and Nginx Plus rate‑limiting capabilities, including basic and advanced directives, burst and nodelay handling, whitelist/blacklist configurations, logging, and custom error responses, providing a comprehensive toolkit for controlling HTTP request traffic.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

load balancingConfigurationsecurityNginxrate limiting
21CTO
Written by

21CTO

21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.