PuTTY keepalive limits: SSH null packets vs TCP keepalives for idle sessions behind NAT
0 reputation · 29 Aug 2026, 05:12 UTC
0 reputation · 29 Aug 2026, 05:12 UTC
I run long-lived SSH sessions from PuTTY through a home NAT router, and idle sessions are dropped after some period of inactivity. PuTTY's Connection panel offers two distinct mechanisms: "Seconds between keepalives", which sends SSH-level null packets, and "Enable TCP keepalives", which relies on the OS socket layer.
My understanding is that the null-packet option defaults to 0 (disabled), only fires while the connection is otherwise idle, and is stored per saved session, while TCP keepalive timing is governed by OS defaults that can be hours on Windows. What I cannot resolve is which mechanism actually resets the NAT's idle timer in practice, and whether enabling both is redundant or harmful.
Constraints: I want to avoid masking genuine outages with an overly aggressive interval, and I would prefer not to tune Windows registry values for TCP keepalives if the application-level option suffices.
35275 reputation · 29 Aug 2026, 12:11 UTC
When you configure Seconds between keepalives, PuTTY sends SSH-level messages (such as SSH_MSG_IGNORE) only when the session is idle. Because these are encrypted payloads wrapped in TCP segments, the NAT router sees a data transfer and resets its session timer.
The Enable TCP keepalives option sets the SO_KEEPALIVE socket option. This delegates the keepalive logic to the Windows TCP/IP stack. Because PuTTY cannot control the timing of these probes, they rely on system-wide defaults. Without registry tuning, these probes fire too infrequently to prevent NAT drops.
To implement and verify this without registry changes:
Seconds between keepalives to 60.Sending SSH keepalive message entries appearing at your defined interval.If sessions still drop with SSH keepalives enabled at 60 seconds, please specify if you are using a VPN or SSH Proxy/Jump host; in those cases, the timeout may be occurring at the proxy level rather than the local NAT.
Use comments to ask for clarification. Post a solution as an answer.
35,275 reputation · 29 Aug 2026, 06:31 UTC
The SSH-level null packet (SSH_MSG_IGNORE) is sent only when the channel has no application data, but because it carries encrypted payload, most NAT/firewall devices treat it as active traffic and reset their idle timers. TCP keepalives are bare ACK probes that many home routers ignore for timeout calculations, so they rarely help unless you lower the OS probe interval via the Windows registry. Enabling both adds negligible overhead; the SSH keepalive will fire first if its interval is shorter, making the TCP keepalive a harmless fallback. You can verify the behavior with Wireshark or by checking netsh int ip show global for the KeepaliveTime setting.