Nginx Rate Limiting: Token‑Bucket, Leaky‑Bucket Algorithms and Configuration Examples
This article explains the principles of token‑bucket and leaky‑bucket rate‑limiting algorithms, shows how Nginx implements them with the limit_req and limit_conn modules, and provides detailed configuration examples—including burst, nodelay, and custom status codes—to control request rates and concurrent connections.
Rate‑Limiting Algorithms
The token‑bucket algorithm generates tokens at a fixed rate, stores them in a bucket, discards excess tokens when the bucket is full, and requires a request to consume a proportional number of tokens before it can be processed; if tokens are insufficient, the request is queued.
The leaky‑bucket algorithm treats incoming requests as water poured into a bucket that drains at a constant rate; overflow is discarded. It buffers bursts but does not allow them to exceed the drain rate.
Comparison
Leaky‑bucket strictly limits the real‑time processing speed, while token‑bucket allows limited bursts by separating token storage from request queuing.
Nginx Modules for Rate Limiting
limit_req_module (Leaky‑Bucket)
Configuration directives: limit_req_zone – defines a shared memory zone to store request counters (e.g., limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;). limit_req – applies the zone to a location, optionally with burst (buffer size) and nodelay (process bursted requests immediately). limit_req_log_level – sets log level for delayed requests. limit_req_status – custom HTTP status code for rejected requests.
Syntax: limit_req zone=name [burst=number] [nodelay];
Default: —
Context: http, server, locationlimit_conn_module (Connection Limiting)
Limits the number of simultaneous connections per key (usually client IP). limit_conn_zone – defines a memory zone for storing connection counters (e.g., limit_conn_zone $binary_remote_addr zone=addr:10m;). limit_conn – applies the limit to a location (e.g., limit_conn addr 1;). limit_conn_log_level – log level for connection limiting. limit_conn_status – custom status code for rejected connections.
Syntax: limit_conn zone number;
Default: —
Context: http, server, locationPractical Examples
Example 1 – Simple Rate Limiting
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;
server {
location / {
limit_req zone=mylimit;
}
}This limits each IP to 2 requests per second. Requests exceeding the limit are rejected after 500 ms because Nginx counts in milliseconds.
Example 2 – Burst Buffering
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;
server {
location / {
limit_req zone=mylimit burst=4;
}
}With burst=4, up to four excess requests are queued; the rest are dropped. In a test of six requests within 10 ms, one is processed immediately, four are queued, and one is rejected.
Example 3 – Burst with nodelay
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;
server {
location / {
limit_req zone=mylimit burst=4 nodelay;
}
}Adding nodelay makes queued requests start processing immediately, reducing overall response time while keeping the same success rate.
Example 4 – Custom Status Code
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;
server {
location / {
limit_req zone=mylimit burst=4 nodelay;
limit_req_status 598;
}
}When the limit is exceeded, Nginx returns HTTP 598 instead of the default 503.
References
Nginx rate‑limiting and connection‑limiting modules, source code notes, and related articles.
Architecture Digest
Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
