Battle ready Nginx

Garrett Albright's picture

Here's a great article about performance-related Nginx configuration directives. I suggest you give it a read if performance is a concern for you. Not only does it tell you what directives and values to use, it also explains with an adequate level of depth what the directives actually mean and the effect they'll have on your site.


Garrett, thanks for sharing

bhosmer's picture

Garrett, thanks for sharing this. You were right, it really does have a good step-by-step explanation about what each directive does and is for.

I beg to differ

perusio's picture

there's nothing to see there. You could get a better view of things if go to the official docs at:

Also @Garret the guy is very Linux centric (epoll set explicitly?). It has been for some time automatic the selection of the event notification mechanism. So in *BSD it will select kqueue if available and in Linux epoll.


chilic's picture

gzip_min_length 256;
gzip_comp_level 4;


keepalive_timeout 20;

Why this option so huge?

You don't need to spend cpu

brianmercer's picture

You don't need to spend cpu time compressing (and uncompressing on the client side) something so small that it will barely benefit from the compression, so there is a minimum size.

Compression level is a balance between cpu time and saving bandwidth.

The default for keepalive_timeout is 75 seconds. You want to keep the connection open so that when the person finishes reading a page and goes to the next that the connection is still established and you save the server the effort of creating a new one. Balance this against using resources on the server to keep the connection open. With apache prefork you want keepalives to be tiny because it opens a thread for each connection. nginx and apache worker can handle much higher keepalives.

These things are configurable because one setting does not suit all use cases. Decisions should be made depending on your specific content, load, and server capacity.

Even then

perusio's picture
  • I don't see how a 75 seconds keepalive is going to:

keep the connection open so that when the person finishes reading a page and goes to the next that the connection is still established and you save the server the effort of creating a new one.

  • I think that either you get on immediately to next page, hence in less than 75 seconds, or it takes more than 75 seconds to read.

  • Keeping open connections should be kept to a minimum unless you have very slow processes. We agree that a page that takes more than 10 s to load is not a "normal" page.

  • Long keepalives set you up for DoS attacks by trying to use up all available workers up to maximum of connections each one accepts.

I didn't say that 75 seconds

brianmercer's picture

I didn't say that 75 seconds was the magic number, I said that 75 seconds is the default that Igor placed in nginx if you don't set this explicitly. The creator of nginx, someone who we probably acknowledge has a good understanding of the http protocol, thinks that 75 is a decent number.

I suppose it depends on your content whether 75 seconds is enough to view a page.

Keep alives are a feature designed to spare your server the overhead of creating new connections, and improving client performance for some clients.

As for server resources, Igor states that "10,000 inactive HTTP keep-alive connections take about 2.5M memory" so it's not memory intensive.

As for something like slowloris consuming your resources, that would depend on how determined and resourceful they are. Clearly nginx memory is not the problem.

But you should set a high rlimit if you're worried about this, since it becomes a matter of file descriptors for each connection. I see that you recommend 8192 for rlimit, (That's per worker, so could be several times that depending on your server), whereas the author of that article sets his at 100,000. I just checked mine and I have worker_rlimit_nofile of 102400. You'd need an awful lot of DOS nodes to beat that.

That's really about all you can do in the web server settings to mitigate attacks. Keep alives can improve user experience for some clients and I'm not going to give up that performance on the worry that some day I'm going to get hit with a new attack. If you're that concerned about getting a DDOS attack then there's other steps you can take. Until I somehow manage to piss off someone with a bot net, I'm going to err on the side of client performance.

Was Keep-Alive actually

Garrett Albright's picture

Was Keep-Alive actually intended to keep connections open between page loads? I assumed it was just meant to keep the connection open between downloading the page and downloading all its resources…

From what I can find it's

brianmercer's picture

From what I can find it's flexible. For custom applications, keep alives of hours or days might make sense.

For web pages, the developers of the web browsers set upper limits on the client end:

IE: 60 seconds
FireFox: 300 seconds
Chrome: 300 seconds
Safari: 30 seconds
Opera: 120 seconds

So there's no use in setting a keep alive higher than 5 minutes for a web page. Other than that, it's a balance between server resources and client performance.

Well let me rephrase that.

brianmercer's picture

Well let me rephrase that. There's plenty of other things you can do in web server settings to mitigate attacks. But low keep alives doesn't need to be one of them.