Keepalives and reconnects get configured in the same breath and solve different problems, which is why tuning one rarely fixes the other. A keepalive sends small traffic to keep a state entry alive or to notice that a peer stopped answering. A reconnect tears down what is broken and builds the relationship again, including keys, addresses and routes. Pick the mechanism that matches the failure rather than the one whose knob you already know. Two questions decide it: is the path dead, or is something between the peers forgetting it?

When the mapping is the problem

A tunnel that dies only after minutes of silence is usually losing a translation entry rather than a peer. WireGuard's PersistentKeepalive exists for NAT and firewall state, and the project's own notes frame it that way rather than as a health check. An interval of a few tens of seconds keeps an entry warm, while a packet every second is a battery decision and not a reliability one. OpenVPN arrives at the same place through ping and ping-restart, which notice silence first and then act on it.

Those settings are not interchangeable across protocols either. An IKEv2 dead-peer policy, an OpenVPN ping timer and a WireGuard keepalive answer the same question with three different syntaxes and three different defaults, so copying a number between them is guesswork dressed as tuning.

When the relationship is gone

If the peer changes address, the credential expires or the far end restarts, small packets are not the repair. The reconnect has to rebuild state: obtain an address, reinstall routes, renegotiate keys, and in some deployments reauthenticate a user.

Clients that reconnect unattended hold a certificate or a stored secret. A client that would prompt a human fails exactly when nobody is present, which is the scenario where the reconnect mattered. That is a design choice made months earlier rather than a setting you can change during an outage.

What neither one proves

A tunnel can be reconnected, keyed and routed while the service behind it is down, and a keepalive can hold a mapping open for a session whose server has been gone for hours. Both mechanisms can report success while the thing you actually care about is unavailable.

That is why the test ends at a real request. Send something through the tunnel after the interval you care about, then separately trigger the failure you designed for: an idle period for the mapping case, a restart or an address change for the reconnect case.

Blocking direct traffic is a separate decision

A reconnect loop can be perfectly healthy while an application quietly uses the ordinary route, which is a leak rather than a failure. If the requirement is that nothing leaves outside the tunnel, say so explicitly in the client configuration and prove it by taking the tunnel down and watching what still connects. Neither mechanism implies that behaviour, and no amount of retry discipline establishes it.

Record which mechanism ran and whether a new request succeeded afterwards. Those two facts are what the next engineer needs, and neither is visible in a status icon. A log line saying the client reconnected is not the same as a request that worked.

Write the policy, not just the number

Put the pair in one sentence: the idle interval, the liveness threshold, what triggers a rebuild, and what the client does while it retries. Without that sentence, every future incident reopens the same argument about whether the keepalive is too short or the reconnect is too slow.

The WireGuard notes on limitations are a useful reminder that the keepalive is a workaround for middleboxes rather than a general liveness design. Read that limitation before raising the frequency in response to a problem it cannot solve.

Makomi ya ndenge moko