A peer that stops passing traffic does not thereby lose its key, and a fresh handshake does not prove that anyone renewed permission to use it. WireGuard's timers keep keys fresh and packets flowing; they do not model a user logging out after a set number of minutes. Three questions get confused here, and each one has different evidence. The distinction decides which tool you reach for.

Three questions, one command output

Operators ask whether a peer is reachable, whether it has been active, and whether it is still allowed. The first is protocol state, the second is traffic counters and the third is authorization. Only the first two can be read from a WireGuard interface, and they are routinely used to answer all three.

QuestionEvidence it needsWhat does not answer it
Is the peer reachable now?A recent handshake and a working return pathAn interface that exists
Has it been active?Transfer counters moving over timeA handshake timestamp alone
Is access still granted?The configuration or controller that authorizes itAny protocol timer

Read the rows as three separate investigations. The first two are cheap and can be answered from the interface's own counters. The third needs the configuration that grants access, which lives in a different file or a different system. Choosing the wrong row is how a protocol timer gets asked to do a policy's job.

What the timers actually govern

The protocol defines constants for handshake retry, transport key rotation and rejection of packets protected by an old key. They respond to traffic and to state, not to a calendar or to a policy that says a person may connect until 17:00. That is why an idle peer can look inactive for hours and still be authorized.

PersistentKeepalive is often mistaken for the missing timeout. It sends authenticated empty packets to keep a NAT mapping alive, and setting it to zero stops those packets without revoking anything.

Read the runtime state per peer, using the public key rather than the comment:

wg show wg0 latest-handshakes
wg show wg0 transfer

A recent handshake says that one handshake completed. It does not say that the private service behind the tunnel is reachable, and an old timestamp can belong to a peer that is simply quiet.

Why an idle peer is not a logged-out peer

WireGuard has no session object with a start and an end. A peer is a public key with allowed addresses, and the handshake that protects its traffic is replaced as needed without any user-visible login. Treating the absence of recent traffic as a logout reverses the model.

If the real complaint is that a connection fails after sitting idle, the cause is usually elsewhere: a NAT mapping that expired, a device that slept, or a firewall that dropped state. Test by sending traffic from the far side and by starting a new flow, and compare what changes.

Put the deadline where the authorization lives

If access must end at a specific time, the deadline belongs to whatever grants the access. A controller that issues peer configurations can require a renewed approval before it hands out a new one, and that is a property of the controller rather than a hidden parameter on the interface.

For hand-managed peers, removal has to reach both places: the running interface and the saved configuration. Removing the peer only at runtime is undone by a restart or a reconciliation loop, which restores the identity you thought had expired:

sudo wg set wg0 peer <public-key> remove
sudo wg-quick save wg0

Then test the boundary rather than the label. Confirm the peer is rejected after the deadline, confirm the renewal path works, and confirm the state survives a reload of the manager. A handshake age is a useful operational signal, and it is not an access record.

Erthyglow kevrennek