How to Configure an Nginx Rate Limit

Nginx rate limiting uses two directives: limit_req_zone defines the limit, limit_req applies it. Get the rate or burst wrong and you'll 503 legitimate users. Here's how to set it correctly.

DevOps Engineernginxrate-limitingflask

The two directives

Nginx rate limiting is a leaky-bucket built from a pair:

# http {} - define a zone: key = client IP, rate = allowed average
limit_req_zone $binary_remote_addr zone=api:10m rate=50r/s;

server {
  location /api/ {
    # location {} - apply the zone, with a burst buffer
    limit_req zone=api burst=50 nodelay;
    proxy_pass http://backend;
  }
}

burst + nodelay (the part everyone gets wrong)

Without a burst, nginx rejects the instant a client exceeds the exact rate - even a normal page that fires a few requests at once gets 503. burst is a queue of extra requests allowed temporarily:

burst=50 nodelay is the usual "feels normal to users, still capped" setting.

The classic failure: a too-tight limit 503s everyone

A config like rate=1r/m (one request per minute) with no burst will 503 almost all real traffic - the backend looks healthy because nginx is rejecting requests before they reach it. The fix is a realistic rate plus a burst:

limit_req_zone $binary_remote_addr zone=api:10m rate=50r/s;   # was 1r/m
limit_req zone=api burst=50 nodelay;                          # was no burst

Reloading the limit

After changing the rate, a full restart is safer than nginx -s reload - reload keeps the shared-memory zone's in-flight counters, which can keep rejecting requests right after the change. Validate then restart:

nginx -t && nginx -s stop && nginx

Return 429 instead of 503 for rejections with limit_req_status 429; - it's the correct "too many requests" code and clients handle it better.

Want to try it hands-on? HeyDevJob gives you this exact setup in a live cloud workspace in your browser - edit it, run it, and see it work. Free, nothing to install.

Try it in a workspace →

What you'll practice

FAQ

How do I rate limit in nginx?

Define a zone with limit_req_zone $binary_remote_addr zone=api:10m rate=50r/s; in the http block, then apply it in a location with limit_req zone=api burst=50 nodelay;.

Why is nginx returning 503 after I added a rate limit?

The limit is too tight or has no burst, so normal traffic exceeds it and nginx rejects requests before they reach the backend. Raise the rate and add burst=... nodelay.

What do burst and nodelay do in limit_req?

burst allows a queue of extra requests above the steady rate (so a normal page firing several requests isn't blocked); nodelay serves those queued requests immediately instead of spacing them out.

Keep learning

Fix the Nginx 502 Bad GatewayDevOps projectRecover a Crashed Linux ServiceDevOps projectCorrect a Postgres Port MismatchDevOps projectDevOps roadmapStep by step to hiredDevOps interview questionsSTAR answersAll DevOps projectsProjects hub

Learn it by doing. Open this in a live cloud workspace, make the change yourself, and keep a record of the work you can share.

Open the workspace →