Keep-Alive is very important feature of HTTP protocol. It allows to make several HTTP requests over single TCP connection. This provides a great performance gain, since otherwise establishing many TCP connections will produce alot of unnecessary networking overhead.
Keep-Alive in web servers
Each web server, whether it is Nginx, Apache of a load balancer like Varnish, have their own way of enabling Keep-Alive and specifying its timeout. Let’s review best practices and how to enable it properly.
Apache
You can add the following to enable keep-alive connections to Apache server:
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 100
There is one main catch to enabling this in Apache. It’s not really a memory efficient server, especially when you are running Apache with mod_php. Enable keep-alive connections in Apache only when you have enough RAM to keep many connections open.
Nginx
Nginx with its default configuration already has keep-alive enabled with 75 seconds timeout. This is a great default. You would rarely want to tweak it.
However, you might actually want to increase it when Nginx is used behind Varnish. This will be beneficial in order to have Varnish and Nginx keep connection to each other:
http {
# 6m for Varnish
keepalive_timeout 300s;
...
}
Varnish
Backend Connections
Varnish will respect “Connection: close” header set by the backend. So if you have not enabled Keep-Alive in your backend server (Nginx, Apache), it will be also disabled in Varnish. As a result the each request will establish new TCP connection to backend every time.
Ideally, enable keepalive connections in your backend server and monitor backend reuse count in varnishstat
. It should be much higher than connection count.
In some situations though (backend server is on a different network device with poor firewall config, etc.) this kind of setup may cause 503 Backend fetch failed error. In that case you may want to disable keepalive configuration on the backend server.
Client Connections
KeepAlive in Varnish for client connections (read, your browser) is controlled by timeout_idle startup parameter.
In Varnish 4, its default is 5 seconds. Depending on resources available, you may want to set it up higher, i.e. 75.
This will allow for better client-side performance:
DAEMON_OPTS="-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} \
-f ${VARNISH_VCL_CONF} \
-T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} \
-p thread_pool_min=${VARNISH_MIN_THREADS} \
-p thread_pool_max=${VARNISH_MAX_THREADS} \
-p timeout_idle=75 \ #
-S ${VARNISH_SECRET_FILE} \
-s ${VARNISH_STORAGE}"