Set Up Rate Limiting with Leaky Bucket Algorithm in Nginx
Nginx came with a rate limit module called ngx_http_limit_req_module
, which is quite handy for throttling harmful requests like DoS attack. And the module uses the leaky bucket algorithm to handle the connections, it could allow certain amount of burst requests in a short period of time to suit the use cases.

503
Set Up Rate Limiting
Before setting up rate limiting in Nginx you'll need a working Nginx server, refer to this guide for the setup.
Define Zone
First by defining a limit_req_zone
in http
block, it takes three parameters:
- Key - Identification of the requests, normally IP address in binary format (
$binary_remote_addr
) is used. - Zone
- Name - Name of the zone.
- Size - Size of the storage.
1m
can store 8,000 ~ 16,000 states according to the official documentation.
- Rate - Determined how many request is allowed in a period of time.
1r/s
means 1 request per second.
Here is a zone named general
with 10m
storage and allow 1r/s
for each $binary_remote_addr
:
http {
limit_req_zone $binary_remote_addr zone=general:10m rate=1r/s;
...
}
Nginx config
Apply to Route
Apply your limit_req_zone
to a route with limit_req
in http
, server
, location
blocks, it takes three parameters as well:
- Zone - Zone name.
- Burst (Optional) - Maximum amount of burst requests allowed before dropping them.
- Delay (Optional) - Maximum amount of burst requests allowed before delaying them.
nodelay
to serve them immediately.
Basic
Apply the general
zone without burst allowed, every request exceeding 1r/s
is dropped:
limit_req zone=general;
Nginx config
With Burst
Apply the general
zone with 3
burst allowed, but every request exceeding 1r/s
is delayed and exceeding 3r/s
is dropped:
limit_req zone=general burst=3;
Nginx config
With Burst and Delay
-
Delay
Apply the
general
zone with3
burst allowed, but every request exceeding2r/s
is delayed and exceeding3r/s
is dropped:limit_req zone=general burst=3 delay=2; Nginx config
-
No delay
Apply the
general
zone with3
burst allowed, every request exceeding3r/s
is dropped:limit_req zone=general burst=3 nodelay; Nginx config
Set Status Code
By default, every request exceeding the rate limit will be closed with status code 503
, which indicates Service Unavailable
.
If this is not desired, you can change it to something like 429
(Too Many Requests
) with limit_req_status
in http
, server
, location
blocks:
limit_req_status 429;
Nginx config
Full Example
Here is a full example demonstrating the use of multiple limit_req_zone
:
http {
limit_req_zone $binary_remote_addr zone=general:10m rate=6r/s;
limit_req_zone $binary_remote_addr zone=static:1m rate=2r/s;
limit_req_zone $binary_remote_addr zone=api:1m rate=1r/s;
limit_req_status 503; # redundant, since it's default
limit_req zone=general burst=12 delay=9;
server {
...
location /static/ {
limit_req zone=static burst=4 nodelay;
root /static;
}
location /api/ {
limit_req_status 429;
limit_req zone=api;
proxy_pass http://127.0.0.1:3000;
}
}
}
Nginx config