I am not sure if you fully understand Nginx’s ngx_http_limit_req_module module:

Nginx has NO *request* limit. Nginx is only offering a *rate* limit.

So when you write

> rate=5r/m sets the allowed request rate from the same IP to 5 requests per minute.

I would expect exactly that: Within a time window of 60 seconds, I can do 5 requests. It doesn’t matter if I will fire these 5 requests together in the first second or distribute equally within my time window.

But this is not what is happening. Instead, when you set “5r/m” you are instructing Nginx to apply a *rate* limit, which translate to 60 seconds / 5 requests = accepting a request every 12 seconds.

Please test it with a simple loop like

while true;
curl -i https://kaspars.net/blog/xmlrpc.php
sleep 1
done

The first request will be successful at say 03:35:00.
The next request at 03:35:01 won’t get accepted due to rate limit.
This will happen for the next 11 requests (due to “sleep 1” in our test script).
The 13th request at 03:35:13 will be the next request which will be accepted.

It is even more complicated: Internal, Nginx is using an interval of 100ms.

So yes, in the end, only 5 requests from the client within 60 seconds were accepted. But from from the behavior, it is not what I would expect in this context. Do you disagree?

It would be really great to tell a client, “Wait, you already posted 5 times to /wp-login.php in a minute, now you have to wait N seconds before you can try again” but this is not possible with stock Nginx.