A real-world latency investigation across an OPNsense exit node, a Pi Zero W enrolled node, and an Android client running a mixed-version Tailnet.
I run Tailscale across a small home lab: an OPNsense router acting as an exit node, a headless Raspberry Pi Zero W enrolled as a node, and my Android phone as the client. It works well. But a question nagged at me: does routing all traffic through the exit node affect how my phone reaches other devices in the Tailnet, specifically the Pi?
MagicDNS was enabled. I wanted to know whether toggling the exit node changed resolution behavior or introduced measurable latency differences. What I found was more interesting than a simple yes or no.
This is a naturally mixed-version Tailnet, which reflects a realistic support scenario. The phone runs the newest version of the three; the Pi is two minor versions behind the exit node.
Three tools, two variables, four test runs. The Pi Zero W is enrolled in the Tailnet as dryer.tailXXXXXX.ts.net with a Tailscale IPv4 of 100.x.x.x. All tests ran from Termux on the Android client.
The two variables tested: exit node active vs exit node disabled, with MagicDNS active in both states. Tests ran back-to-back within each state to capture both cold-connection and warm-connection behavior.
The first question was simple: does MagicDNS resolve the Pi's hostname correctly when the exit node is active? The answer is yes, consistently and correctly, in both states.
In both exit node states, the hostname resolved to the correct Tailscale IPv4 address every time. No split-brain DNS, no resolution failure, no difference in which address was returned. The OPNsense/Unbound combination does not appear to conflict with MagicDNS in this configuration.
MagicDNS hostname resolution is stable and unaffected by exit node state in an OPNsense configuration. This behavior is expected per Tailscale's documentation but is not explicitly confirmed for this specific setup anywhere in their public knowledge base or community forums.
Every first ping after an idle period produced a dramatically higher latency than subsequent packets. This held true regardless of exit node state.
The back-to-back test design was deliberate. Run 1's cold first ping (453–592ms) vs Run 2's warm first ping (59–76ms) proves the spike is connection-establishment overhead, not a measurement artifact. When the peer connection is already warm from Run 1, Run 2 starts fast.
Tailscale's own documentation explains this. From their connection types knowledge base: all connections start relayed through a DERP server, and Tailscale then attempts to upgrade them to a direct connection. That negotiation is what the first-ping spike captures. The packet I sent while Tailscale was still deciding how to route it took the long way around.
The cold-connection first-ping spike is the DERP-to-direct handoff in real time, captured via standard ICMP ping. Tailscale documents this transition using tailscale ping, but ICMP ping data showing the same behavior in an exit node configuration has not been publicly documented to my knowledge, and I was unable to find any existing reference to it. Counterintuitively, the exit node ON state produced a lower cold spike (453ms vs 592ms), suggesting the OPNsense node maintains a warmer peer path to the Pi than direct phone-to-Pi routing does.
The nmap host discovery scan removed the cold-connection variable entirely and measured steady-state reachability latency. The difference here was clear and consistent.
| Tool | Exit ON · run 1 | Exit ON · run 2 | Exit OFF · run 1 | Exit OFF · run 2 |
|---|---|---|---|---|
| ping (cold) | 453 ms | 76 ms | 592 ms | 60 ms |
| ping (warm avg) | 67 ms | 72 ms | 65 ms | 64 ms |
| nmap -sn | 160 ms | 140 ms | 78 ms | 83 ms |
nmap showed roughly 2x higher latency with the exit node active (140–160ms) vs disabled (78–83ms). This is the cost of the extra hop: traffic from the phone routes out through OPNsense and back, even when the destination is another device in the same Tailnet. The warm ping averages, by contrast, were nearly identical across both states.
When an OPNsense exit node is active, intra-Tailnet latency measured by nmap is approximately 2x higher than with the exit node disabled. This is expected behavior — the traffic is taking an extra hop — but the magnitude is worth knowing. Warm ICMP ping averages converge regardless of exit node state, suggesting the overhead is most visible at the host-discovery layer rather than in sustained traffic.
None of these findings represent a bug. They represent undocumented but predictable behavior of three Tailscale features: the OPNsense plugin, exit node routing, and MagicDNS. A user troubleshooting "Tailscale feels slow" or "my first ping always spikes" would find no existing documentation connecting these dots in this specific configuration.
The most actionable insight is the cold-connection spike. Users who ping a Tailnet device after any idle period may consistently see 450–600ms on the first packet before settling to 60ms. The Tailscale app on Android does provide some visual indication of this: long-pressing a device and using the built-in ping tool will show "Relayed connection" in red during the initial handoff, transitioning to "Direct connection" once the peer path is established. This explains the spike for users who know to look for it. However, for users running standard ICMP ping from a terminal, there is no equivalent indication - the spike appears with no context, and reads as a performance problem. It is not.