Skip to main content

Implementing Rate Limiting

1. Defining Limit Request Zone

Directive Values Description
limit_req_zone zone=name:rate Defines a shared memory zone to hold the state of requests and the rate at which they are allowed
zone name:size Name of the zone and size of shared memory (e.g., zone=one:10m)
rate number Rate of requests per second (e.g., rate=1r/s) or per minute (e.g., rate=5r/m)

Example: Basic rate limiting zone

limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

Example: Rate limiting with burst

limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
limit_req zone=one burst=5 nodelay;

2. Applying Rate Limit

Directive Description Example
limit_req Enables rate limiting based on a defined zone limit_req zone=api_limit burst=10;
limit_req_zone Defines a rate limit zone with a key and rate limit_req_zone $binary_remote_addr zone=api_limit:10m rate=1r/s;
burst Number of requests allowed to exceed the rate limit before being rejected limit_req zone=api_limit burst=5;
nodelay Disables delay for burst requests limit_req zone=api_limit burst=5 nodelay;

Example: Basic Rate Limit Configuration

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

    server {
        listen 80;
        location /api/ {
            limit_req zone=api_limit burst=5 nodelay;
            proxy_pass http://backend;
        }
    }
}
Note: The $binary_remote_addr variable is used to uniquely identify clients.
Warning: Ensure that the zone size is sufficient to handle expected traffic. Zone size is limited to 1MB per 10,000 entries.

3. Setting Burst Parameter

Directive Values Description
limit_req burst=5 Sets the maximum number of requests allowed to exceed the rate limit before being dropped or delayed

Example: Configuring Burst Limit

limit_req_zone $binary_remote_addr zone=api:10m rate=1r/s;
server {
    location /api/ {
        limit_req zone=api burst=5 nodelay;
        proxy_pass http://backend;
    }
}
Note: The burst parameter allows temporary bursts of requests to be handled without immediate rejection, improving user experience during short spikes in traffic.

4. Using No Delay Option

Directive Description Values Notes
limit_req Enables rate limiting for a given zone zone=name, burst=number, nodelay When nodelay is used, requests are not delayed but immediately rejected if the burst limit is exceeded

Example: Using nodelay in limit_req

limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;

server {
    location /api/ {
        limit_req zone=api nodelay;
        proxy_pass http://backend;
    }
}
Note: The nodelay option is useful for APIs where immediate rejection is preferred over queuing requests.

5. Configuring Connection Limit

Directive Values Description
limit_conn_zone zone=name:size Defines a shared memory zone to store connection state
limit_conn zone=name; burst=number; nodelay Applies connection limits to a zone

Example: Basic Connection Limiting

http {
    limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;
    limit_conn_zone $server_name zone=conn_limit_per_server:10m;

    server {
        listen 80;
        server_name example.com;

        limit_conn conn_limit_per_ip 10;
        limit_conn conn_limit_per_server 100;
    }
}

Example: Burst Connection Limiting

http {
    limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;

    server {
        listen 80;
        server_name example.com;

        limit_conn conn_limit_per_ip 10;
        limit_conn burst=5 nodelay;
    }
}
Note: The limit_conn_zone directive must be placed in the http block, not inside a server block.
Warning: If limit_conn_zone is not configured properly, the connection limiting will not work as expected.

6. Applying Connection Limit

Directive Values Description
limit_conn_zone zone=name:size Defines a shared memory zone to store connection state
limit_conn zone=name:connections Applies the connection limit to a zone

Example: Configuring Connection Limits

http {
    limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;
    limit_conn_zone $server_name zone=conn_limit_per_server:10m;

    server {
        listen 80;
        server_name example.com;

        location / {
            limit_conn conn_limit_per_ip 10;
            limit_conn conn_limit_per_server 100;
        }
    }
}
Note: The limit_conn_zone directive must be defined at the http level, and limit_conn is applied per location or server block.

Key Points

  • limit_conn_zone creates a shared memory zone to track connections.
  • limit_conn enforces limits on the number of concurrent connections.
  • Use $binary_remote_addr for IP-based limits or $server_name for server-specific limits.

7. Setting Rate Limit Status

Directive Values Description
limit_req_status 429 Status code returned when rate limit is exceeded
limit_req_status 403 Alternative status code for rate limit exceeded
limit_req_status 503 Service unavailable status for rate limit exceeded

Example: Configuring 429 Status Code

limit_req_status 429;

server {
    listen 80;
    server_name example.com;

    location /api/ {
        limit_req zone=api_req burst=5 nodelay;
        proxy_pass http://backend;
    }
}
Note: The limit_req_status directive controls the HTTP status code returned when a client exceeds the rate limit. Common values are 429 (Too Many Requests), 403 (Forbidden), or 503 (Service Unavailable).

8. Logging Rate Limit Events

Directive Description Default
limit_req_log_level Sets the logging level for rate limit events error

Example: Configuring Log Level

limit_req_log_level info;
Note: Setting limit_req_log_level to info or lower will log rate limit events at that level.
Log Format Description Example
$limit_req_status Indicates whether the request was limited limited or allowed
$limit_req_key Key used for rate limiting 192.168.1.1

Example: Custom Log Format

log_format rate_limit "$remote_addr - $limit_req_status [$time_local] "
"Request: $request_uri, Key: $limit_req_key";

access_log /var/log/nginx/rate_limit.log rate_limit;

9. Using Multiple Rate Limits

When implementing rate limiting in Nginx, you can apply multiple limits to different resources or paths. This allows for granular control over traffic and helps prevent abuse.

Directive Description Example
limit_req Applies rate limiting to a location or server block. limit_req zone=api_limit burst=10;
limit_req_zone Defines a shared memory zone for storing rate limit data. limit_req_zone $binary_remote_addr zone=api_limit:10m rate=1r/s;
burst Number of requests allowed to exceed the rate limit before being delayed or dropped. limit_req zone=api_limit burst=5;
nodelay Disables delay for burst requests. limit_req zone=api_limit burst=5 nodelay;

Example: Applying Multiple Rate Limits

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

    server {
        listen 80;
        location /api/ {
            limit_req zone=api_limit burst=10;
        }

        location /static/ {
            limit_req zone=static_limit burst=20;
        }
    }
}
Note: Each limit_req_zone directive defines a unique zone with its own rate and burst settings. These zones can be applied to different locations or paths independently.

10. Excluding IPs from Rate Limiting

Directive Description Example
limit_req_zone Defines a shared memory zone for rate limiting limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
limit_req Applies rate limiting to a location or server block limit_req zone=api burst=5 nodelay;
limit_req_dry_run Logs rate limiting without enforcing it limit_req_dry_run zone=api;

Example: Exclude Specific IPs from Rate Limiting

limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;

server {
    listen 80;
    server_name example.com;

    # Exclude specific IPs from rate limiting
    location /api/ {
        limit_req zone=api burst=5 nodelay;
        if ($remote_addr ~ "192.168.1.100|10.0.0.50") {
            limit_req off;
        }
    }

    location / {
        # Apply rate limiting to all other requests
        limit_req zone=api burst=5 nodelay;
    }
}
Note: The if directive is evaluated for each request, so it's best to avoid complex conditions or use map for better performance.

Key Points

  • Use if with a regex pattern to match excluded IPs
  • Set limit_req off; to disable rate limiting for matching IPs
  • Place the exclusion logic before applying rate limits in the location block

11. Implementing Dynamic Rate Limits

Directive Description Example
limit_req Defines the rate limit for a zone limit_req zone=api_limit burst=5;
limit_req_zone Defines a rate limit zone with key and rate limit_req_zone $binary_remote_addr zone=api_limit:10m rate=1r/s;
burst Number of requests allowed to exceed the rate limit before blocking limit_req zone=api_limit burst=5;
nodelay Do not delay requests, block immediately limit_req zone=api_limit burst=5 nodelay;

Example: Dynamic Rate Limiting Configuration

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

    server {
        listen 80;
        location /api/ {
            limit_req zone=api_limit burst=5 nodelay;
            proxy_pass http://backend;
        }

        location /api/fast/ {
            limit_req zone=api_limit_5s burst=10 nodelay;
            proxy_pass http://backend;
        }
    }
}
Note: The $binary_remote_addr variable is used to identify clients uniquely.
Warning: Setting rate=0r/s disables rate limiting.

12. Using Delay Parameter

Directive Values Description
limit_req delay Enables rate limiting with a delay for requests exceeding the limit.

Example: Configuring rate limiting with delay

server {
    location /api/ {
        limit_req zone=api_zone delay=10s;
        proxy_pass http://backend;
    }
}
Note: The delay parameter allows the server to queue requests that exceed the rate limit instead of dropping them immediately.

Was this article helpful?