1

I'm trying to rate limit the nginx connections, however it doesn't seem to work as expected. I tried to test it using 2 and 10 requests per second.

First, 2 requests per second

limit_req_zone $binary_remote_addr zone=myzone:10m rate=2r/s;
limit_req_status 429;
server {
  listen *:80;
  server_name 172.23.97.94;
  root /var/www/html;
  index index.html;
  location / {
    limit_req zone=myzone;
    try_files $uri $uri/ =404;
  }
}

Testing via curl:

for i in {1..2}; do curl -I -s "http://172.23.97.94" | head -n 1; done
HTTP/1.1 200 OK
HTTP/1.1 429 Too Many Requests

Access.log confirms there are only 2 requests in the same time, however, the second request gets 429:

172.23.106.65 - - [08/Feb/2023:17:10:35 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.68.0"
172.23.106.65 - - [08/Feb/2023:17:10:35 +0000] "HEAD / HTTP/1.1" 429 0 "-" "curl/7.68.0"

But if I do the same request with a sleep of 0.5 seconds, it goes well:

for i in {1..2}; do curl -I -s "http://172.23.97.94" | head -n 1; sleep 0.5; done
HTTP/1.1 200 OK
HTTP/1.1 200 OK

Second, 10 requests per second

limit_req_zone $binary_remote_addr zone=myzone:10m rate=10r/s;
    limit_req_status 429;
    server {
      listen *:80;
      server_name 172.23.97.94;
      root /var/www/html;
      index index.html;
      location / {
        limit_req zone=myzone;
        try_files $uri $uri/ =404;
      }
    }

Testing via curl:

for i in {1..10}; do curl -I -s "http://172.23.97.94" | head -n 1; done
HTTP/1.1 200 OK
HTTP/1.1 429 Too Many Requests
HTTP/1.1 429 Too Many Requests
HTTP/1.1 429 Too Many Requests
HTTP/1.1 429 Too Many Requests
HTTP/1.1 429 Too Many Requests
HTTP/1.1 429 Too Many Requests
HTTP/1.1 429 Too Many Requests
HTTP/1.1 429 Too Many Requests
HTTP/1.1 429 Too Many Requests

Access.log confirms there are only 10 connections in the same time, but only the first gets 200:

172.23.106.65 - - [08/Feb/2023:17:14:53 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.68.0"
172.23.106.65 - - [08/Feb/2023:17:14:53 +0000] "HEAD / HTTP/1.1" 429 0 "-" "curl/7.68.0"
172.23.106.65 - - [08/Feb/2023:17:14:53 +0000] "HEAD / HTTP/1.1" 429 0 "-" "curl/7.68.0"
172.23.106.65 - - [08/Feb/2023:17:14:53 +0000] "HEAD / HTTP/1.1" 429 0 "-" "curl/7.68.0"
172.23.106.65 - - [08/Feb/2023:17:14:53 +0000] "HEAD / HTTP/1.1" 429 0 "-" "curl/7.68.0"
172.23.106.65 - - [08/Feb/2023:17:14:53 +0000] "HEAD / HTTP/1.1" 429 0 "-" "curl/7.68.0"
172.23.106.65 - - [08/Feb/2023:17:14:53 +0000] "HEAD / HTTP/1.1" 429 0 "-" "curl/7.68.0"
172.23.106.65 - - [08/Feb/2023:17:14:53 +0000] "HEAD / HTTP/1.1" 429 0 "-" "curl/7.68.0"
172.23.106.65 - - [08/Feb/2023:17:14:53 +0000] "HEAD / HTTP/1.1" 429 0 "-" "curl/7.68.0"
172.23.106.65 - - [08/Feb/2023:17:14:53 +0000] "HEAD / HTTP/1.1" 429 0 "-" "curl/7.68.0"

But if I do the same request with a sleep of 0.01 seconds, some of them are 200, while other are 429:

for i in {1..10}; do curl -I -s "http://172.23.97.94/device/1" | head -n 1; sleep 0.01; done
HTTP/1.1 200 OK
HTTP/1.1 429 Too Many Requests
HTTP/1.1 429 Too Many Requests
HTTP/1.1 429 Too Many Requests
HTTP/1.1 429 Too Many Requests
HTTP/1.1 200 OK
HTTP/1.1 429 Too Many Requests
HTTP/1.1 429 Too Many Requests
HTTP/1.1 429 Too Many Requests
HTTP/1.1 200 OK

Am I doing something wrong? Or the rate limit simply does not work as expected ?

catalin
  • 335

1 Answers1

0

I ran into this problem too - 10r/s is really one request per each tenth of a second.

Here's a related Stack Overflow post: https://stackoverflow.com/questions/62262540/ideal-config-for-nginx-rate-limiting

Here's the article they reference from nginx talking about it: https://www.nginx.com/blog/rate-limiting-nginx/

It seems a bad decision to me, since it's common to have one page load a few ajax requests, and the way this works those get delayed when doing any rate limiting.

From the article, it looks like there's ways around this with the 'nodelay' option then doing a two stage rate limiting.

limit_req zone=ip burst=12 delay=8;

Which allows 8 requests all at once, then after that it'll delay them up until there's 12 in the queue, then it will start denying them.

Giacomo1968
  • 58,727
Kevin
  • 111