'How to limit the number of user 's requests made within a minute in nginx?

I am setting up the API server in NGINX , so I applied rate limiting in it so that I can resist the user's request but it is not working properly which I wanted that server should work. I want 10 req/min , After reaching its limit that user should get 429 error. Current problem is that after reaching the limit I can still access the record after waiting for 1s . My Config of NGINX is:-

limit_req_zone $binary_remote_addr zone=XXXX:1m rate=10r/m;
location / {
     limit_req zone=XXXX burst=9 nodelay;
     limit_req_status 429;
     proxy_pass http://XXXX:x000/api/;
}


Solution 1:[1]

I've been looking for an answer all morning, I'm in your same situation (but with a different config). But, unfortunately, it seems that rate just calculates the frequency requests limit.

So 10r/m just means "1 request every 6 seconds" and not "only allow 10 requests per minute".

From the nginx blog:

In the example, the rate cannot exceed 10 requests per second. NGINX actually tracks requests at millisecond granularity, so this limit corresponds to 1 request every 100 milliseconds (ms). Because we are not allowing for bursts (see the next section), this means that a request is rejected if it arrives less than 100ms after the previous permitted one.

Also from a FreeCodeCamp post:

For NGINX, 300r/m and 5r/s are treated the same way: allow one request every 0.2 seconds for this zone

As per your configuration, you have a burst of 9 requests and nodelay, that means that you can accept 10 requests in the first 6 seconds, and then burst will free up 1 request every 6 seconds. So I'd say you should be able to make around 19 successful requests, all the others will be denied with 429, in your case.

Again from the nginx blog post:

when a request arrives “too soon”, NGINX forwards it immediately as long as there is a slot available for it in the queue. It marks that slot as “taken” and does not free it for use by another request until the appropriate time has passed (in our example, after 100ms).

Please let me know if I answered your doubts :)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 tyzion