Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

With the nginx HttpLimitReq module requests can be limited by IP. However, I'm not understanding what the "nodelay" option does.

If the excess requests within the limit burst delay are not necessary, you should use the nodelay

limit_req   zone=one  burst=5  nodelay;
share|improve this question
up vote 6 down vote accepted

The documentation here has an explanation that sounds like what you want to know:

The directive specifies the zone (zone) and the maximum possible bursts of requests (burst). If the rate exceeds the demands outlined in the zone, the request is delayed, so that queries are processed at a given speed

From what I understand, requests over the burst will be delayed (take more time and wait until they can be served), with the nodelay options the delay is not used and excess requests are denied with a 503 error.

This blog post (archive.org) gives good explanation how the rate limiting works on nginx:

If you’re like me, you’re probably wondering what the heck burst really means. Here is the trick: replace the word ‘burst’ with ‘bucket’, and assume that every user is given a bucket with 5 tokens. Every time that they exceed the rate of 1 request per second, they have to pay a token. Once they’ve spent all of their tokens, they are given an HTTP 503 error message, which has essentially become the standard for ‘back off, man!’.

share|improve this answer
1  
I think you're incorrect, the nginx manual states: "Excessive requests are delayed until their number exceeds the maximum burst size". Note that until exceeds maximum burst is entirely different meaning than over the burst that you said. You also conflated burst with excess requests, I believe excess requests means it's above the zone, while it may still be below the maximum burst. – Hendy Irawan Dec 19 '14 at 7:09

The way I see it is as follows:

  1. Requests will be served as fast as possible until the zone rate is exceeded. The zone rate is "on average", so if your rate is 1r/s and burst 10 you can have 10 requests in 10 second window.

  2. After the zone rate is exceeded:

    a. Without nodelay, further requests up to burst will be delayed.

    b. With nodelay, further requests up to burst will be served as fast as possible.

  3. After the burst is exceeded, server will return error response until the burst window expires. e.g. for rate 1r/s and burst 10, client will need to wait up to 10 seconds for the next accepted request.

share|improve this answer

The setting defines whether requests will be delayed so that they conform to the desired rate or whether they will be simply rejected...somewhat whether the rate limiting is managed by the server or responsibility is passed to the client.

nodelay present

Requests will be handled as quickly as possible; any requests sent over the specified limit will be rejected with the code set as limit_req_status

nodelay absent (aka delayed)

Requests will be handled at a rate that conforms with the specified limit. So for example if a rate is set of 10 req/s then each request will be handled in >= .1 (1/rate) seconds, thereby not allowing the rate to be exceeded, but allowing the requests to get backed up. If enough requests back up to overflow the bucket (which would also be prevented by a concurrent connection limit), then they are rejected with the code set as limit_req_status.

The gory details are here: https://github.com/nginx/nginx/blob/master/src/http/modules/ngx_http_limit_req_module.c#L263 where that logic kicks in when the limit has not yet been passed and now the delay is optionally going to be applied to the request. The application of nodelay in particular from the directive comes into play here: https://github.com/nginx/nginx/blob/master/src/http/modules/ngx_http_limit_req_module.c#L495 causing the value of delay above to be 0 triggering that handler to immediately return NGX_DECLINED which passes the request to the next handler (rather than NGX_AGAIN which will effectively requeue it to be processed again).

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.