IntroductionNGINX is open-source web server software for reverse proxying, caching, web serving, load balancing, and media streaming. Its rate-limiting feature limits the number of HTTP requests a user can make in a given time.Rate limiting defends against web-based attacks like:Brute-force attacks—by slowing them down and limiting bot requests.DDoS attacks prevent server overload by capping incoming requests to a baseline.How NGINX Handles Rate Limiting?NGINX rate limiting uses the "leaky bucket algorithm," common in telecommunications and networking, to manage bursts when bandwidth is limited. Imagine a bucket where water (requests) is poured in and leaks out at a steady rate. If too many requests come in too fast, the bucket overflows, and extra requests are dropped. As they leave the bucket, requests are handled in the order they arrived, one by one.For more details Read our article on Dev.to NGINX Rate Limiting Configuring Basic Rate LimitingRate limiting is set up using two main directives: limit_req_zone and limit_req. Here's an example:limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;server { location /login/ { limit_req zone=mylimit; proxy_pass http://my_upstream; } }The limit_req_zone directive sets the rate-limiting parameters, while limit_req applies it to specific contexts (e.g., requests to /login/).Typically defined in the http block, limit_req_zone uses three parameters:Key: Defines what to limit. In the example, $binary_remote_addr limits each unique IP address based on its binary representation, saving space.Zone: Defines shared memory to store IP address states. For example, 1MB can store around 160,000 addresses. If full, NGINX removes old entries; if needed, it returns a 503 error.Rate: Sets the maximum request rate, e.g., 10 requests per second. Without bursts, requests arriving sooner than 100ms after the previous one are rejected.To enforce rate limiting, limit_req is added to a specific location, like /login/, limiting each IP to 10 requests per second.NGINX Limit Rate with Number of ConnectionsTo limit connections to proxied HTTP resources in NGINX, use the limit_conn directive. It sets the maximum number of connections allowed for a specific resource.For example, to limit connections to a resource named my_resource to 10, use this configuration:http { # ... limit_conn my_resource 10; # ... }Place this directive in the http block of your NGINX configuration, alongside other request processing directives. Use proxy_pass in your server block to specify which proxied resource the limit_conn directive applies to.For example:server { # ... location /my_resource { proxy_pass http://my_backend; } # ... }In this example, requests to /my_resource are sent to http://my_backend, and the limit_conn directive restricts connections to 10.Handling BurstsIf two requests arrive within 100ms, NGINX returns a 503 status code for the second one. This isn't ideal, as applications often have bursts. To handle excess requests, we can buffer them using the burst parameter in the limit_req directive, as shown in this updated configuration:location /login/ { limit_req zone=mylimit burst=20; proxy_pass http://my_upstream; } The burst parameter defines how many excess requests a client can make beyond the rate limit. For example, with a 10 requests per second limit (1 every 100ms) and a queue size of 20, NGINX queues requests that arrive too quickly. If 21 requests come from one IP, NGINX forwards the first request and queues the next 20. It processes queued requests every 100ms and returns a 503 error if more than 20 requests are queued.NGINX Limiting the Request RateUse the limit_req directive in NGINX to limit the request rate to proxied HTTP resources. It sets the maximum request rate, typically in requests per second.For example, to limit requests to a resource named my_resource to 10 per second, use this configuration:http { # ... limit_req zone=my_resource burst=10 nodelay; # ... } Place this directive in the http block of your NGINX configuration. The zone parameter names the resource for rate limiting, and burst sets the max number of requests allowed. The nodelay parameter tells NGINX to reject requests exceeding the rate limit immediately, rather than waiting for the time period to end.Use the proxy_pass directive in your server block to specify which proxied resource the limit_req directive applies to. For example:server { # ... location /my_resource { proxy_pass http://my_backend; } # ... }In this example, requests to /my_resource are proxied to http://my_backend, with the limit_req directive limiting the rate to 10 requests per second.NGINX Limit Rate by Limiting BandwidthTo limit bandwidth to proxied HTTP resources in NGINX, use the limit_rate directive. It sets the maximum data transfer rate for a resource, typically in bytes per second. For example, to limit my_resource to 10 kilobytes per second, use this configuration:http { # ... limit_rate 10k; # ... } Place this directive in the http block of your NGINX configuration. By default, limit_rate applies to all proxied resources, but you can specify a particular resource if needed. For example:server { # ... location /my_resource { proxy_pass http://my_backend; limit_rate 10k; } # ... } In this example, requests to /my_resource are proxied to http://my_backend, with the limit_rate directive limiting bandwidth to 10 kilobytes per second.Advanced Rate Limiting Configuration ExamplesYou can combine basic rate limiting with other NGINX features for more precise traffic control.AllowlistingThis example shows how to rate-limit requests from users not on an allowlist.geo $limit { default 1; 10.0.0.0/8 0; 192.168.0.0/24 0; }map $limit $limit_key { 0 ""; 1 $binary_remote_addr; }limit_req_zone $limit_key zone=req_zone:10m rate=5r/s; server { location / { limit_req zone=req_zone burst=10 nodelay; # ... } } This example uses the geo and map directives. The geo block sets $limit to 0 for allowlisted IPs and 1 for others. The map directive then sets $limit_key as follows:If $limit is 0, $limit_key is an empty string.If $limit is 1, $limit_key is the client's IP address in binary format.So, $limit_key is empty for allowlisted IPs and the IP address otherwise. With an empty string as the key, rate limits are not applied to allowlisted IPs (in 10.0.0.0/8 and 192.168.0.0/24). Other IPs are limited to 5 requests per second. The limit_req directive allows bursts of up to 10 requests with no delay.ConclusionIn conclusion, we have thoroughly covered NGINX’s rate limiting capabilities. We discussed configuring request rates for different locations, utilizing parameters like burst and nodelay to manage traffic spikes, and implementing advanced IP-based limits using geo and map directives. These features enable you to manage and optimize web traffic effectively, ensuring robust application performance and reliability.Read Morehttps://devopsden.io/article/cloudflare-web-performance-and-SecurityFollow us onhttps://www.linkedin.com/company/devopsden/