How to Rate Limit an API with Nginx

Rate limiting protects your API from abuse, accidental client bugs causing request storms, and helps ensure fair usage across all clients. Nginx provides efficient, built-in rate limiting without needing application-level changes.

Basic Rate Limiting Configuration

http {
    limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;

    server {
        location /api/ {
            limit_req zone=api_limit burst=20 nodelay;
            proxy_pass http://127.0.0.1:3000;
        }
    }
}

rate=10r/s allows 10 requests per second per client IP; burst=20 allows short bursts above that rate, up to 20 extra queued requests; nodelay processes burst requests immediately rather than artificially delaying them.

Understanding the Zone Definition

zone=api_limit:10m allocates 10MB of shared memory to track client request rates — sufficient for roughly 160,000 tracked IP addresses, more than enough for most applications.

Applying Different Limits to Different Endpoints

http {
    limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
    limit_req_zone $binary_remote_addr zone=login:10m rate=1r/s;

    server {
        location /api/login {
            limit_req zone=login burst=3 nodelay;
            proxy_pass http://127.0.0.1:3000;
        }

        location /api/ {
            limit_req zone=general burst=20 nodelay;
            proxy_pass http://127.0.0.1:3000;
        }
    }
}

Sensitive endpoints (login, password reset) warrant much stricter limits than general API browsing, since they're common brute-force targets.

Returning a Proper Status Code When Rate Limited

limit_req_status 429;

429 (Too Many Requests) is the correct HTTP status code, letting well-behaved clients know to back off and retry later rather than treating it as a generic error.

Rate Limiting by API Key Instead of IP (More Precise)

If clients authenticate with an API key, rate limit per-key instead of per-IP, avoiding penalizing legitimate users sharing an IP (e.g. behind a corporate NAT) while still controlling individual API key abuse:

limit_req_zone $http_x_api_key zone=apikey_limit:10m rate=100r/m;

Combining Connection Limiting

limit_conn_zone $binary_remote_addr zone=conn_limit:10m;

server {
    location /api/ {
        limit_conn conn_limit 10;
    }
}

Limits simultaneous open connections per IP, complementing the request-rate limiting above.

Logging Rate-Limited Requests

limit_req_log_level warn;

Logs when clients hit the rate limit, helping identify whether limits need adjustment or whether genuine abuse is occurring.

Testing Your Rate Limits

for i in {1..30}; do curl -o /dev/null -s -w "%{http_code}\n" https://api.yourdomain.com/endpoint; done

Confirm you start seeing 429 responses once the configured limit is exceeded.

Setting Different Limits for Authenticated vs Anonymous Requests

map $http_authorization $limit_key {
    ""      $binary_remote_addr;
    default "";
}

limit_req_zone $limit_key zone=anon_limit:10m rate=5r/s;

A common pattern: apply stricter limits to unauthenticated requests, more generous limits once a client has authenticated.

Common Errors

Legitimate traffic getting rate limited — the rate/burst values may be too conservative for genuine usage patterns; review actual traffic data before tightening limits.

Rate limiting has no effect — verify the limit_req_zone directive is in the http block (not server), and limit_req is correctly referenced within the relevant location block.

Best Practices

  • Apply stricter limits to sensitive endpoints (login, password reset) than general browsing
  • Return 429 with appropriate Retry-After headers for well-behaved client handling
  • Monitor rate-limit logs to distinguish genuine abuse from limits that are too conservative

Continue Reading

Browse more articles in Object Storage, Messaging & APIs.

  • nginx rate limiting, api rate limit, 429 too many requests, api protection
  • 0 användare blev hjälpta av detta svar
Hjälpte svaret dig?

Relaterade artiklar

How to Set Up Self-Hosted S3-Compatible Object Storage with MinIO

MinIO is a high-performance, self-hosted object storage server compatible with the S3 API —...

How to Use Object Storage for Application File Uploads

Storing user-uploaded files directly on your application server's disk creates scaling and...

How to Install and Configure RabbitMQ on a VPS

RabbitMQ is a widely-used, robust message broker — enabling applications to communicate...

How to Install and Configure Redis as a Message Queue

Redis, primarily known as a cache, also works well as a lightweight message queue for simpler use...

How to Build and Secure a REST API on a VPS

This guide covers the essential security and architecture practices for deploying a REST API on...