How to Configure Linux TCP Keepalive Parameters using sysctl

The Problem with Idle Connections

In a Linux networking environment, when an application establishes a TCP connection to a remote server (e.g., an SSH session or a database connection pool), the connection remains open until one side explicitly closes it (by sending a FIN packet). However, if the remote server completely loses power, or if a corporate firewall silently drops the routing table, the Linux server will never receive that FIN packet. From the Linux kernel’s perspective, the connection is still perfectly healthy and “ESTABLISHED,” permanently tying up a valuable network socket and consuming memory.

To detect these “dead” connections and forcefully close them, the Linux kernel relies on TCP Keepalive. The kernel occasionally sends an empty ACK packet to the remote server. If the server responds, the connection is kept alive. If it fails to respond after a certain number of attempts, the kernel destroys the socket.

The problem is that the default Linux keepalive settings are incredibly slow. By default, Linux waits a massive 2 hours (7200 seconds) before sending the first probe. For a high-frequency trading application or a load-balanced web server, leaving a dead socket open for two hours is unacceptable. You must tune these parameters using sysctl.

Analyzing the Default Parameters

To view the current keepalive settings in your kernel, run the following command:

sysctl -a | grep keepalive

You will see three critical variables:

  1. net.ipv4.tcp_keepalive_time = 7200 (Wait 2 hours before probing).
  2. net.ipv4.tcp_keepalive_intvl = 75 (Wait 75 seconds between each subsequent probe).
  3. net.ipv4.tcp_keepalive_probes = 9 (Send 9 probes before giving up).

Under these defaults, it takes 2 hours and 11 minutes for Linux to finally close a dead connection.

Tuning the Parameters for High Performance

For modern, highly active web servers (like Nginx or HAProxy), you should configure the kernel to identify a dead connection within a few minutes.

You can temporarily apply new settings using the sysctl -w command (must be run as root):

sudo sysctl -w net.ipv4.tcp_keepalive_time=600
sudo sysctl -w net.ipv4.tcp_keepalive_intvl=15
sudo sysctl -w net.ipv4.tcp_keepalive_probes=5

With this highly tuned configuration, the kernel waits only 10 minutes (600 seconds) of inactivity before sending a probe. If it gets no response, it sends 4 more probes spaced 15 seconds apart. A completely dead connection is now detected and purged from RAM in exactly 11 minutes and 15 seconds.

Making the Changes Persistent

Any changes made with the sysctl -w command are stored entirely in RAM. The moment the server reboots, the Linux kernel will revert to the 2-hour default.

To make the tuning permanent, you must append the variables to the system configuration file.

Open /etc/sysctl.conf using a text editor (like nano) with root privileges:

sudo nano /etc/sysctl.conf

Scroll to the bottom of the file and add your new directives:

# Custom TCP Keepalive Tuning for High-Volume Web Traffic
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 15
net.ipv4.tcp_keepalive_probes = 5

Save and close the file. To force the kernel to read the file immediately without restarting the server, execute:

sudo sysctl -p

Your server’s networking stack is now highly aggressive, ensuring that dead sockets are rapidly reclaimed and recycled for new incoming client connections.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.