Knowledge

How to configure rate limiting in nginx

#Security

Rate limiting protects login pages, APIs, and expensive endpoints from abuse and brute-force attacks. nginx does this with the built-in limit_req module. Here is how to configure it.

Published by Mark van Eijk on June 23, 2026 · 1 minute read

  1. How nginx rate limiting works
  2. Define a rate-limit zone
  3. Apply the limit to a location
  4. Return 429 instead of 503
  5. Protect a login endpoint against brute force
  6. Apply and test

How nginx rate limiting works

nginx rate limiting has two parts: you define a zone that tracks request rates per client in the http block, then apply that zone to the locations you want to protect. The limit_req module uses a leaky-bucket algorithm, so a steady rate is allowed while bursts are smoothed out or rejected.

Define a rate-limit zone

Add this inside the http block (in nginx.conf):

limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
  • $binary_remote_addr keys the limit on the client IP address (compact form).
  • zone=mylimit:10m names the zone and reserves 10 MB of shared memory — enough for roughly 160,000 IPs.
  • rate=10r/s allows 10 requests per second per IP. Use r/m for per-minute limits on sensitive endpoints.

Apply the limit to a location

Reference the zone inside a server or location block:

location /login {
    limit_req zone=mylimit burst=20 nodelay;
    # ... your usual proxy_pass or fastcgi_pass
}
  • burst=20 lets a short spike of up to 20 queued requests through instead of rejecting them immediately.
  • nodelay serves those burst requests right away rather than spacing them out — usually what you want for web traffic.

Return 429 instead of 503

By default nginx rejects limited requests with 503 Service Unavailable. 429 Too Many Requests is more accurate and friendlier to API clients:

limit_req_status 429;

Protect a login endpoint against brute force

A tight per-minute limit is ideal for login and password-reset pages:

limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;

location = /login {
    limit_req zone=login burst=3 nodelay;
    limit_req_status 429;
    # ...
}

Apply and test

Check the configuration before reloading so a typo doesn't take the site down:

sudo nginx -t
sudo systemctl reload nginx

You can confirm it's working by hammering the endpoint and watching for 429 responses:

for i in $(seq 1 20); do curl -s -o /dev/null -w "%{http_code}\n" https://example.com/login; done

Rate limiting pairs well with other server-level protections such as a Content Security Policy in nginx and the broader checklist in optimizing web application security.

Subscribe to our newsletter

Do you want to receive regular updates with fresh and exclusive content to learn more about web development, hosting, security and performance? Subscribe now!

Related articles

How to extract private key from PFX file

Rate limiting protects login pages, APIs, and expensive endpoints from abuse and brute-force attacks. nginx does this with the built-in limit_req module. Here is how to configure it.

Read more →

How to extract the certificate from a PFX file

Rate limiting protects login pages, APIs, and expensive endpoints from abuse and brute-force attacks. nginx does this with the built-in limit_req module. Here is how to configure it.

Read more →