Linux TCP keepalive
In line with the increase in internet users, the traffic and workload on the web server is also increased. Hence, the webmaster or system administrator needs to make sure that the web server is able to accommodate a sufficient number of TCP connections. If your web server has begun to show an increase in the number of visitors, you may start planning to perform basic tcp tuning on the linux operating system.
On average, most people that visit the website or blog that comes from search engines only read a page just for 1-2 minutes. After they got the answer for what they really want, they simply leave the page and visit other sites. But the old opened connection still remains and unused for a long time.
For low and average number of website visitors, the default values for the keepalive parameter should be sufficient. But for high concurrency web server or in a busy server, decrease timeouts on TCP sockets can help to clean up the tcp connections from clients that have been disconnected. This can be done by changing the default value of tcp_keepalive setting in sysctl.conf.
What is TCP Keepalive
TCP keepalive is a mechanism for TCP connections that help to determine whether the other end has stopped responding or not. TCP will send the keepalive probe contains null data to the network peer several times after a period of idle time. If the peer does not respond, the socket will be closed automatically. The application will then receive a notification about the socket closure, which it should handle in the correct manner.
Most of the operating systems and hosts that support TCP also support TCP Keepalive. Basically, tuning some of the settings in sysctl.conf file really help speeding things up under heavy usage.
Tunable TCP settings can be found on /proc/sys/net/ipv4
TCP Keepalive
TCP Keepalive works by probing the other side of the connection when it has detected an idle state:
- Each TCP connection is associated with a set of settings in the Kernel. Whenever a new socket is created with the SO_KEEPALIVE option, the Kernel settings are applied.
- Each connection in an ESTABLISHED state is tracked and associated to a timer. When a connection is idle for longer than the configured period, the OS sends the remote node a keepalive probe packet with no data in it and the ACK flag turned on.
- Because of the TCP/IP specifications, this is handled similarly to a duplicate ACK. The remote node will simply reply with no data and an ACK packet. The remote node doesn’t need to implement anything on their end, and this logic is implemented as part of the TCP protocol.
The Keepalive probe is sent with no payload Length 0 (Len=0) and the Sequence number (Seq No) as the Sequence number that the receiver is expecting subtracted by 1 (SEG.SEQ = SND.NXT-1). The remote node will simply acknowledge the packet by replying it with a TCP ACK, since the segment was mimicking a retransmission of another previously acknowledged segment.
By default, Linux-based OSes has the TCP Keepalive configured to be triggered after 7200 seconds (2 hours). This is significantly higher than the idle timeout settings you may find with network appliances running in the cloud.
Default values of TCP KeepAlive setting in Linux OS
TCP Keepalive is configured as Linux Kernel parameters and is available at /proc/sys/net/ipv4/
cat /proc/sys/net/ipv4/tcp_keepalive_time
7200
cat /proc/sys/net/ipv4/tcp_keepalive_intvl
75
cat /proc/sys/net/ipv4/tcp_keepalive_probes
9
tcp_keepalive_time = 7200 (seconds)
tcp_keepalive_intvl = 75 (seconds)
tcp_keepalive_probes = 9 (number of probes)
- tcp_keepalive_time
- the interval between the last data packet sent (simple ACKs are not considered data) and the first keepalive probe; after the connection is marked to need keepalive, this counter is not used any further
- This setting determines the time (in seconds) that a connection must be idle before the first keepalive packet is sent. The default value is 7200 seconds, or 2 hours. This means that if there is no data exchange on a connection for 2 hours, the system will send a keepalive packet to the remote host to check if the connection is still active.
- tcp_keepalive_intvl
- the interval between subsequential keepalive probes, regardless of what the connection has exchanged in the meantime
- This setting specifies the interval (in seconds) between successive keepalive packets if no response (acknowledgment) is received from the remote host. The default value is 75 seconds. If the first keepalive packet does not receive a response, the system will send additional keepalive packets every 75 seconds until it receives a response or reaches the maximum number of allowed probes (as defined by tcp_keepalive_probes).
- tcp_keepalive_probes
- the number of unacknowledged probes to send before considering the connection dead and notifying the application layer
- This setting defines the maximum number of unacknowledged keepalive packets that the system will send before considering the connection dead. The default value is 9 probes. If the system sends 9 keepalive packets without receiving a response, it assumes the connection is dead and closes it.
With the default TCP keepalive settings, the system will send a keepalive packet after 2 hours of inactivity on a connection. If it does not receive a response, it will continue sending keepalive packets every 75 seconds. After 9 unacknowledged keepalive packets, the system will close the connection, considering it dead.
TCP keepalive process waits for two hours (7200 secs) for socket activity before sending the first keepalive probe, and then resend it every 75 seconds. As long as there is TCP/IP socket communications going on and active, no keepalive packets are needed.
Configure TCP Keepalive for a Web Server
Let’s assume you are running a web server with a moderate amount of traffic. You want to ensure that idle connections are detected and closed in a timely manner without putting too much load on the server.
I recommend using the following settings:
net.ipv4.tcp_keepalive_time = 60 # 1 minute
net.ipv4.tcp_keepalive_intvl = 10 # 10 seconds
net.ipv4.tcp_keepalive_probes = 6 # 6 probes
In this example, keepalive packets will be sent after 1 minute of inactivity. If there is no response from the remote host, additional keepalive packets will be sent every 10 seconds until a total of 6 packets have been sent without a response. If there is still no response, the connection will be considered dead and closed.
Making changes persistent to reboot
1. Edit your /etc/sysctl.conf
~] vi /etc/sysctl.conf
2. Add the following setting
...
net.ipv4.tcp_keepalive_time = 60
net.ipv4.tcp_keepalive_intvl = 10
net.ipv4.tcp_keepalive_probes = 6
3. To load settings, enter the following command
sysctl -p
# or for linux systems with sudo
sudo sysctl -p
or reboot entire system
systemctl reboot
KeepAlive Parameter Details
- net.ipv4.tcp_keepalive_time = 60
- Decrease the time default value for tcp_keepalive_time connection from 7200 seconds to 60 seconds. This determine the time of connection inactivity after which the first keep alive request is sent. Parameter below shows that the TCP will begin sending keepalive null packets after 1 minute.
- net.ipv4.tcp_keepalive_intvl = 10
- The following parameter (tcp_keepalive_intvl) determines the keepalive probe will resend every 10 seconds after first keep alive probe. This reduce from 75 seconds to 10 seconds gap or time interval between each of the keep alive probes.
- pv4.tcp_keepalive_probes = 6
- Next parameter (tcp_keepalive_probes) is expressed in the pure number. The following setting determine the number of probes before timing out. We recommend to reduce number of retransmitted from 9 to 6 before the connection is considered broken.