Nginx Feature Request: Delay 503 limit_req responses
We would like to delay the 503 response to clients which exceed the
limit_req value rather then send an immediate 503. The delay would be
in milliseconds or in tenths of a second increments for example.
We are not trying to slow down those clients who are obviously abusive
or malicious. Those ips are blocked at the firewall with custom
scripts. We are trying to slow down valid clients who use overly
aggressive programs, but have legitimate access our servers.
The nginx server in question is used to serve large data downloads. We
want to serve as many people as we can without using excessive CPU
time or sending billions of 503 error network packets. According to
our logs we spend approximately 1.3% of our outgoing bandwidth on 503
responses to valid clients. I believe simply by adding in a 200ms
delay we could reduce outgoing 503 bandwidth from 1.3% to less then
0.2% saving us time and money.
Our current setup:
The following directives allow a client to make 100 requests with no
delay. After 100 requests the client is limited to 61 requests per
minute. Client requests over 61/60 seconds are returned an error 503
immediately for every subsequent request.
limit_req_zone $binary_remote_addr zone=one:10m rate=61r/m;
limit_req zone=one burst=100 nodelay;
What does everyone think of slightly delaying the 503 response?
Using the same limit_req code above the client could exceed our limit
of 61 req per 60 sec and we would still send back a 503, but now we
delay the response by 200ms. Notice the delay at the end of the
following directive. The delay would slow the next request by the
client by slowing our response.
limit_req_zone $binary_remote_addr zone=one:10m rate=61r/m delay=200ms;
What does delaying the response solve?
The problem we see is over aggressive download accelerators, http
scanners or broken scripts. A client application which gets an
immediate 503 will just send another request right away and we will
send them another 503 right away. This looping behavior uses CPU
resources, network time and can be a significant drain on resources.
If nginx could delay the 503 by a user specified time the excessive
client requests and 503 error loops will be reduced. The client would
wait till it gets a response from the server before sending another
request believing the packet is still in the network. The side effect
of the delay is the client would be slowed and perhaps lower its
request rate below our limit_req value.
Problems with delaying the 503 response?
One issue we see with delaying the response to the client is holding
open the connection. Not sure if this is a real problem because the
client will probably use the same connection for their next immediate
request anyways. There may be other problems with the delay we have
not thought of yet.
Thanks for everyone’s time. We just wanted to post this request in
case anyone else also thought the idea was valid and a delayed 503 was
a decent solution.