Nginx Rate Limiting: Request Rate, Connection Limits, and Bandwidth Control
This article explains how to configure Nginx for rate limiting, including request rate control, burst handling, whitelisting, connection limits, and upload/download bandwidth throttling, with detailed directives, examples, and code snippets to ensure proper service stability.
1 Overview
Rate limiting is a method of service degradation that protects a system by restricting input and output traffic. When a website is exposed to the public, normal user traffic, crawlers, malicious attacks, or sudden spikes can overload the server, causing slow responses or crashes. By limiting a portion of requests—such as frequent requests from the same IP—when concurrency is high, the server can continue to serve other requests correctly.
nginx provides two rate‑limiting methods: limiting request rate and limiting connection count.
It also supports download/upload speed limiting.
2 Limiting Request Rate
nginx's ngx_http_limit_req_module uses the leaky‑bucket algorithm. Imagine a bucket that fills with water (incoming requests) and drains at a constant rate; if the inflow exceeds the outflow, the bucket overflows and excess requests are dropped.
2.1 Normal Rate Limiting
The two main directives are limit_req_zone and limit_req :
limit_req_zone $binary_remote_addr zone=test:10m rate=2r/s;
server {
location / {
limit_req zone=test;
}
}key : defines the limiting object; $binary_remote_addr stores the client IP in binary form to save memory (4 bytes for IPv4, 16 bytes for IPv6). zone : shared memory area for storing access information; e.g., test:10m can hold about 160 000 IP records. rate : maximum request rate, e.g., 2r/s means at most 2 requests per second (actually one request every 500 ms). The default response for excess requests is 503, configurable via limit_req_status .
Both directives must be used together for the limit to take effect.
2.2 Handling Burst Traffic
To allow short spikes, add the burst parameter:
limit_req_zone $binary_remote_addr zone=test:10m rate=2r/s;
server {
location / {
limit_req zone=test burst=5;
}
}burst=5 permits up to 5 additional requests to be queued when the rate is exceeded. Requests beyond the burst are rejected. Each queued request is processed every 500 ms, so the 5th request waits 2 seconds before being served.
Adding nodelay removes the waiting time for queued requests:
limit_req_zone $binary_remote_addr zone=test:10m rate=2r/s;
server {
location / {
limit_req zone=test burst=5 nodelay;
}
}Although queued requests are processed immediately, the release rate remains 500 ms per request, so overall throughput is still limited by rate .
2.3 Whitelisting
Use ngx_http_geo_module and ngx_http_map_module to exempt 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=mylimit:10m rate=2r/s;If the key is an empty string (whitelisted IP), the limit does not apply; otherwise the binary IP address is used.
2.4 Duplicate limit_req Directives
Multiple limit_req directives in the same location are all applied; the most restrictive rule wins:
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=mylimit:10m rate=2r/s;
limit_req_zone $binary_remote_addr zone=myLimit2:10m rate=10r/s;
server {
location ~* \.(html)$ {
limit_req zone=mylimit burst=5 nodelay;
limit_req zone=myLimit2 burst=5 nodelay;
}
}Whitelisted users bypass mylimit but are still limited by myLimit2 (10 r/s). Non‑whitelisted users must satisfy both limits, with the stricter 2 r/s taking effect.
3 Limiting Connection Count
The ngx_http_limit_conn_module provides limit_conn_zone and limit_conn directives:
limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;
server {
location ~* \.(html)$ {
limit_conn perip 10;
limit_conn perserver 100;
}
}perip 10 : each IP can hold at most 10 simultaneous connections. perserver 100 : the virtual host can handle up to 100 concurrent connections in total.
Note: the connection is counted only after the request header has been processed by the backend server.
4 Upload/Download Rate Limiting
Implemented via the limit_rate and limit_rate_after directives in ngx_http_core_module .
4.1 limit_rate
server {
location / {
limit_rate 4k;
}
}Sets a per‑connection bandwidth limit (default unit: bytes/s). The limit applies to each connection, so two connections can use up to 8 kB/s together.
4.2 limit_rate_after
server {
location / {
limit_rate_after 500k;
limit_rate 4k;
}
}Data transferred before the specified amount (e.g., 500 kB) is not throttled; throttling starts afterward. Commonly used for segmented downloads or to allow initial video buffering without speed restriction.
4.3 proxy_limit_rate
Similar to limit_rate but limits the rate between nginx and upstream servers. It requires proxy_buffering to be enabled.
# Syntax:
# proxy_limit_rate rate;
# Default: proxy_limit_rate 0;
# Context: http, server, location4.4 Dynamic Rate Limiting
Variables can be used with limit_rate to achieve dynamic throttling.
Based on Time
map $date_local $limit_rate_time {
default 4K;
~(00:|01:|02:|03:|04:|05:|06:|07:).* 16K;
~(08:|12:|13:|18:).* 8K;
~(19:|20:|21:|22:|23:).* 16K;
}
limit_rate $limit_rate_time;Different time windows map to different bandwidth limits.
Based on Cookie
map $cookie_User $limit_rate_cookie {
gold 64K;
silver 32K;
copper 16K;
iron 8K;
}
limit_rate $limit_rate_cookie;Allows VIP users (e.g., gold) to enjoy higher speeds.
Thank you for reading; hope this helps.
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.