The SSH keepalive mechanism consists of two key parameters in client configuration:
ServerAliveInterval 60
ServerAliveCountMax 2
Contrary to some misconceptions, ServerAliveCountMax
doesn't limit the number of keepalive packets sent during normal operation. Instead, it defines how many consecutive failed keepalive responses will trigger connection termination.
Here's the actual behavior:
- Every
ServerAliveInterval
(60s in example), client sends keepalive request - If server responds, counter resets to 0
- If no response, counter increments by 1
- When counter reaches
ServerAliveCountMax
, connection drops
For different network conditions:
# Stable network (cloud servers)
Host cloud
ServerAliveInterval 30
ServerAliveCountMax 3
# Unstable network (mobile connections)
Host mobile
ServerAliveInterval 15
ServerAliveCountMax 10
To verify your configuration:
ssh -v user@hostname
Look for debug messages containing "Sending keepalive" to confirm the interval is working.
Remember that server-side may have its own timeout settings (ClientAliveInterval
and ClientAliveCountMax
in sshd_config
). For persistent connections, both sides need proper configuration.
If connections still drop prematurely:
- Check for network devices (firewalls, NAT) that might drop idle connections
- Verify TCP keepalive settings at OS level
- Consider using persistent SSH connections with ControlMaster
# Example of persistent connection setup
Host *
ControlMaster auto
ControlPath ~/.ssh/control:%h:%p:%r
ControlPersist 1h
The ServerAliveInterval
and ServerAliveCountMax
parameters work together to maintain SSH connections during periods of inactivity. Here's the technical breakdown:
Host *
ServerAliveInterval 60 # Send keepalive every 60 seconds
ServerAliveCountMax 2 # Max unanswered probes before disconnect
Contrary to some misconceptions, the behavior is precisely defined:
- After
ServerAliveInterval
seconds of inactivity, the client sends an encrypted keepalive message - If no response is received, the client will wait another interval period before retrying
- This continues until
ServerAliveCountMax
consecutive probes go unanswered - Only then does SSH terminate the connection
Consider these real-world cases with different configurations:
# Scenario 1: Aggressive keepalive (5 minute timeout)
Host production-server
ServerAliveInterval 30
ServerAliveCountMax 10 # 30×10 = 300s (5m) total timeout
# Scenario 2: Loose connection (1 hour timeout)
Host development
ServerAliveInterval 300
ServerAliveCountMax 12 # 300×12 = 3600s (1h) total timeout
- These are client-side settings (affects outgoing connections)
- For server-side keepalives, use
ClientAliveInterval
in sshd_config - TCP keepalive (different mechanism) can be enabled with
TCPKeepAlive yes
If keepalives aren't working as expected:
# Verify your settings with:
ssh -G yourhost | grep Alive
# For debugging, add verbose output:
ssh -vvv yourhost
For enterprise environments with strict requirements:
Match host *.corp.example.com
ServerAliveInterval 15
ServerAliveCountMax 4
TCPKeepAlive yes
ExitOnForwardFailure yes