Nginx Rate Limiting and DDoS Protection
limit_req, limit_conn, and fail2ban.
Why Rate Limiting Is Your First Line of Defense
Every public-facing web application faces automated abuse — credential stuffing, scraping, and volumetric DDoS attacks. Nginx's built-in rate limiting modules provide a lightweight, high-performance defense layer that can block 95% of automated traffic before it reaches your application servers.
Understanding Nginx Rate Limiting Modules
Nginx offers two complementary modules for traffic control:
- limit_req — Limits the rate of incoming requests using the leaky bucket algorithm
- limit_conn — Limits the number of concurrent connections from a single source
Configuring limit_req for API Protection
Define a shared memory zone in the http block and apply it to specific locations:
http {
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
server {
location /api/ {
limit_req zone=api burst=20 nodelay;
limit_req_status 429;
proxy_pass http://backend;
}
}
}This configuration allows 10 requests per second per IP, with a burst buffer of 20 requests. The nodelay directive processes burst requests immediately rather than queuing them.
Connection Limiting with limit_conn
http {
limit_conn_zone $binary_remote_addr zone=perip:10m;
server {
location /downloads/ {
limit_conn perip 5;
limit_conn_status 429;
}
}
}This restricts each IP to a maximum of 5 simultaneous connections to the downloads endpoint — ideal for preventing bandwidth abuse.
Layered DDoS Protection Strategy
- Rate limiting at Nginx — Stop volumetric attacks at the edge
- fail2ban integration — Ban repeat offenders at the firewall level
- GeoIP blocking — Restrict traffic from regions you don't serve
- Connection timeouts — Set aggressive timeouts for slowloris-style attacks
fail2ban Integration
Configure fail2ban to monitor Nginx error logs for 429 responses and automatically add iptables rules:
[nginx-limit-req]
enabled = true
filter = nginx-limit-req
action = iptables-multiport[name=nginx, port="80,443"]
logpath = /var/log/nginx/error.log
maxretry = 5
bantime = 3600Advanced: Dynamic Rate Limiting
Use Nginx map directive to apply different rates based on request characteristics:
map $request_uri $limit_key {
~^/api/auth "auth";
~^/api/ "api";
default "general";
}
limit_req_zone $binary_remote_addr zone=auth:10m rate=5r/s;
limit_req_zone $binary_remote_addr zone=api:10m rate=30r/s;
limit_req_zone $binary_remote_addr zone=general:10m rate=50r/s;Monitoring and Tuning
Key metrics to track:
- 429 response rate — Too many false positives means your limits are too aggressive
- Unique IPs hitting limits — Distinguish bots from legitimate traffic spikes
- Requests per second by endpoint — Set limits based on actual usage patterns
Eazy SaaS Tip: Start with generous limits (2x your peak traffic) and tighten gradually. We help clients implement rate limiting with zero false positives using traffic analysis from access logs.