Operations 14 min read

Mastering Nginx Rate Limiting: From Basics to Advanced Configurations

This article explains Nginx's rate‑limiting feature, covering the leaky‑bucket algorithm, basic and advanced directives like limit_req_zone, limit_req, burst, nodelay, whitelist handling, logging, and custom error codes to control request flow and protect services.

Open Source Linux
Open Source Linux
Open Source Linux
Mastering Nginx Rate Limiting: From Basics to Advanced Configurations

How Nginx Limits Traffic

Rate limiting (rate‑limiting) in Nginx is a practical feature often misunderstood or misconfigured; it restricts the number of HTTP requests a user can make within a given time frame, whether a simple GET for a homepage or a POST to a login form.

It can serve security purposes, such as slowing brute‑force password attacks, and can help mitigate DDoS attacks by limiting request rates to typical user values while logging target URLs. More commonly, it protects upstream application servers from being overwhelmed by too many simultaneous requests.

This article introduces the fundamentals and advanced configurations of Nginx rate limiting, applicable to both Nginx and Nginx Plus.

Underlying Algorithm

Nginx uses the leaky‑bucket algorithm, widely employed in networking to handle burst traffic when bandwidth is limited. Imagine a bucket that leaks water at a constant rate while water is poured in; excess water overflows, analogous to excess client requests being discarded.

Leaky bucket diagram
Leaky bucket diagram

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;</code>
<code>server {</code>
<code>    location /login/ {</code>
<code>        limit_req zone=mylimit;</code>
<code>        proxy_pass http://my_upstream;</code>
<code>    }</code>
<code>}
limit_req_zone

defines the shared memory zone and parameters (key, zone size, rate). limit_req enables the limit in a specific context, such as a location block.

Key – identifies the request attribute used for limiting (e.g., $binary_remote_addr).

Zone – shared memory area storing per‑IP state; size determines how many IPs can be tracked.

Rate – maximum request rate (e.g., 10 requests per second, which Nginx tracks in 100 ms intervals).

If Nginx runs out of space for new entries, it removes old ones; if still insufficient, it returns a 503 status. To prevent memory exhaustion, Nginx deletes up to two unused entries per 60 seconds when creating a new entry.

Applying limit_req to a location enforces the defined rate, e.g., limiting each IP to 10 requests per second for /login/.

Handling Bursts

When more requests arrive than the configured rate, Nginx can buffer excess requests using the burst parameter:

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

defines how many requests exceeding the rate can be queued (e.g., 20). Requests beyond the burst limit receive a 503 response.

Zero‑Delay Queuing

Adding nodelay makes queued requests processed immediately without additional delay, preventing the site from appearing slow:

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

With nodelay, requests that arrive “too early” are forwarded instantly if a queue slot is available, while the slot remains occupied for the configured interval (e.g., 100 ms).

Advanced Example: Whitelisting

Combine geo and map to exempt certain IP ranges from rate limiting:

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

IPs in the whitelist receive an empty key, bypassing the limit; all other IPs are limited to 5 requests per second.

Multiple limit_req Directives in One Location

When several limit_req directives apply, the strictest limit wins. Example extending the whitelist configuration:

http {</code>
<code>    limit_req_zone $limit_key zone=req_zone:10m rate=5r/s;</code>
<code>    limit_req_zone $binary_remote_addr zone=req_zone_wl:10m rate=15r/s;</code>
<code>    server {</code>
<code>        location / {</code>
<code>            limit_req zone=req_zone burst=10 nodelay;</code>
<code>            limit_req zone=req_zone_wl burst=20 nodelay;</code>
<code>        }</code>
<code>    }</code>
<code>}

Whitelisted IPs are limited to 15 r/s, others to the stricter 5 r/s.

Logging

By default, Nginx logs limited requests at the error level:

2015/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"

Fields include limiting status, excess count, zone, client IP, server, request line, and host. The log level can be changed with limit_req_log_level, e.g., to warn:

location /login/ {</code>
<code>    limit_req zone=mylimit burst=20 nodelay;</code>
<code>    limit_req_log_level warn;</code>
<code>    proxy_pass http://my_upstream;</code>
<code>}

Custom Error Codes

By default, exceeded limits return HTTP 503. Use limit_req_status to return a different code, such as 444:

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

Deny All Requests for a Specific Location

location /foo.php {</code>
<code>    deny all;</code>
<code>}

Summary

The article covered Nginx and Nginx Plus rate‑limiting features, including per‑location request rates, burst and nodelay parameters, whitelist/blacklist configurations, and logging of delayed or rejected requests.

ConfigurationNginxRate Limitinglimit_reqburstnodelay
Open Source Linux
Written by

Open Source Linux

Focused on sharing Linux/Unix content, covering fundamentals, system development, network programming, automation/operations, cloud computing, and related professional knowledge.

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.