What exactly does keepalive_timeout work?

Hi,

I’d like to understand how keepalive_timeout works. The description
in the documentation isn’t very clear and I couldn’t get an answer to
my satisfaction on nginx IRC.

People seem to have their own understanding of how keepalive_timeout
works and they are very different.

  1. For e.g.
    https://github.com/roots/trellis/blob/master/roles/nginx/templates/nginx.conf.j2
    describes the directive like this:

    How long to allow each connection to stay idle; longer values are

better
# for each individual client, particularly for SSL, but means that
worker
# connections are tied up longer. (Default: 65)

So according to the statement keepalive_timeout is to be used to
tell how long a server needs to keep the connection alive AFTER
serving all the requests.

And this commenter seems to agree:
http://serverfault.com/q/331762#comment665957_331764

[It’s] only a timeout during which server waits for another request
up to [the limit set by] keepalive_requests. So it is not important
how much time it takes for the full page to load […] BTW the max.
time connection is kept open is almost:

keepalive_timeout * keepalive_requests
  1. Then there are people understand the function of
    keepalive_timeout like so: HTTP Keep Alive and TCP keep alive - Stack Overflow

HTTP Keep-Alive is a feature of HTTP protocol. The web-server,
implementing Keep-Alive Feature, has to check the connection/socket
periodically (for incoming HTTP request) for the time span since it
sent the last HTTP response (in case there was corresponding HTTP
Request). If no HTTP request is received by the time of the configured
keep-alive time (seconds) the web server closes the connection.

Similar opinion from another: keepalive - How to adjust nginx keepalive_timeout? - Server Fault

There isn’t a good one-size-fits-all answer; if most client browsers
are able to load all the resources on a page in 5 seconds then 5
seconds is just fine […]

So according to these people the directive is to be calculated in such
a way that in that given time (on an average) a web page on your site
and its contents (HTML, CSS, JS, images) are completely loaded on most
clients.

THE QUESTION: So which one is it? (1) or (2)? Who’s right?

You generally want as long a keepalive timeout as you’re able to
tolerate.
Closing the connection after 5 seconds for example means a full new TCP
and
TLS handshake has to occur if the user clicks a link after 5 seconds,
resulting in a minimum of two RTTs before content, causing a slow
loading
experience. If you have long pages that could take minutes to read
before a
user loads another page, then for best performance you want keepalive at
5+
minutes for example. Keep in mind this is an upper limit - the browser
is
free to choose when to close the connection on the client too.

The reason you will sometimes see recommendations to have a low
keepalive
timeout is to improve performance of legacy forking web servers where
each
client connection consumed an entire process and thus lots of memory.
Having lots of idle clients on such servers caused heavy memory usage
and
was not recommended. Of course nginx has no such problem since it’s
event
based.

Hi Richard, thank you for your reply.

Since posting on this mailing-list I’ve come across some very good
(and credible) descriptions of Keep-Alive, and the best thing is that
they are all in agreement, i.e. no conflicting views. I’ll quote them
here as a note to self and for everyone; they explain it all.

((1)) https://tweaked.io/guide/general/webservers/

""The purpose of keep-alive is simple in theory; rather than clients
having to open a fresh connection to your server for each request they
make (index, then CSS, then images), they open one connection.

When the initial connection is made that socket is kept open, rather
than beign closed, such that further requests can be using it.

From the client point of view this improves things, as rather than
making the overhead to establish, use, and close, multiple connections
only one is used.

However the server is left keeping sockets open in the hope that
further requests will come, and if they don’t resources are being
needlessly consumed which could be better spent on handling fresh
visitors.

Generally people suggest leaving a small number of sockets available
for keep-alive, or only keeping sockets open for a short period of
time - such as five seconds - after which time the chances of a
further request are minimal.“”

((2)) https://support.microsoft.com/en-us/kb/813827

""When Internet Explorer establishes a persistent HTTP connection with
a Web server (by using Connection: Keep-Alive headers), Internet
Explorer reuses the same TCP/IP socket that was used to receive the
initial request until the socket is idle for one minute. After the
connection is idle for one minute, Internet Explorer resets the
connection. A new TCP/IP socket is used to receive additional
requests. You may want to change the HTTP KeepAliveTimeout value in
Internet Explorer.

If either the client browser (Internet Explorer) or the Web server has
a lower KeepAlive value, it is the limiting factor. For example, if
the client has a two-minute timeout, and the Web server has a
one-minute timeout, the maximum timeout is one minute. Either the
client or the server can be the limiting factor.

By default, Internet Explorer has a KeepAliveTimeout value of one
minute and an additional limiting factor (ServerInfoTimeout) of two
minutes. Either setting can cause Internet Explorer to reset the
socket.“”

((3)) http://kb.mozillazine.org/Network.http.keep-alive.timeout

""Amount of time in seconds to keep keep-alive connections alive.
Default: 115 seconds.

Setting this to more than 115 probably won’t help and will make things
worse.“”

NOTE: More on this in ((5)).

((4))
http://kb.mozillazine.org/Network.http.max-persistent-connections-per-server

On the maximum number of HTTP keep-alive connections the application
can have open at once to a single server: “Anything above 10 is
excessive.”

((5))
https://blog.fastmail.com/2011/06/28/http-keep-alive-connection-timeouts/

NOTE: That blog post is a must-read and also states when one would
want to have long HTTP keep-alive timeout on their server.

After following 4/5 links above, I have no questions on how the
keepalive_timeout directive works or what it’s intended for. I’m
satisfied!