Drill · routing · difficulty ●●○ · 6 min

Everything through the exit node crawls at 2 Mbps

"The exit node makes my internet unusable, but Tailscale transfers to my other machines run at full speed. The exit node box must be broken."

Which failure areas the drills cover connectivity 3 drills identity 3 drills policy 2 drills dns 2 drills routing 3 drills platform 2 drills bar length is the count, not a difficulty or importance score

The ticket

The Customer runs a distributed engineering team. Their egress node, cloud-1, sits inside the Singapore office network so that traffic to regional services leaves from an office IP. The Customer’s laptop, node-a, is on the US East coast. This week every browser tab through the exit node is unusable: speed tests read 2 Mbps down, video calls drop. But a large file copy from node-a to node-b, a Linux box on the same tailnet, runs near line rate. The Customer has concluded the exit node host is faulty and wants it rebuilt today.

“Tailscale itself is clearly fine, my transfers to node-b are fast. Something is wrong with the exit node machine. Can you rebuild it this afternoon?”

Evidence provided

The first responder collected status, a path check, and a throughput number before touching anything.

$ tailscale status
100.64.0.11   node-a       ops@       macOS   -
100.64.0.42   cloud-1      tag:exit   linux   active; exit node; relay "sin", tx 8114224 rx 71982416
100.64.0.17   node-b       ops@       linux   active; direct 203.0.113.88:41641, tx 992216 rx 1114328
$ tailscale ping cloud-1
pong from cloud-1 (100.64.0.42) via DERP(sin) in 243ms
pong from cloud-1 (100.64.0.42) via DERP(sin) in 239ms
pong from cloud-1 (100.64.0.42) via DERP(sin) in 244ms

$ tailscale ping node-b
pong from node-b (100.64.0.17) via 203.0.113.88:41641 in 12ms
$ curl -s https://speed.example.net/api | jq .download_mbps
2.1

The two status lines already tell most of the story. Per the connection types documentation (kb-connection-types), “direct” plus an IP and port means a real UDP path; “relay” plus a region code means every packet is riding a DERP server. node-b is direct. cloud-1, the exit node, is relayed through the Singapore DERP region.

Hypothesis tree

Three explanations fit “internet slow through exit node, tailnet fast to another peer.” They make different predictions, so cheap checks separate them.

Hypothesis tree: slow exit node trafficAll traffic via exit node caps at 2 Mbps(peer traffic to node-b is fast)A. Exit node host saturatedCPU, NIC, or provider capB. Path to exit node isDERP relayed, not directC. DNS or MTU pathologypages feel slow, bandwidth fineDiscriminator: iperf3 fromlab-vm-1 on the same LAN;host CPU and NIC metricsDiscriminator: tailscale statusshows relay vs direct;tailscale ping never upgradesDiscriminator: raw iperf3 by IPstill reads 2 Mbps, so it isbandwidth, not name lookup

Branch B carries the accent because the evidence already leans that way: the status line says relay “sin” for cloud-1 and direct for node-b.

Investigation

  1. Compare the two peer paths in tailscale status. cloud-1 shows relay "sin"; node-b shows direct 203.0.113.88:41641. This rules out the Customer’s core assumption that “Tailscale is fine” as a single statement. Tailscale maintains a separate path per peer; one peer being direct proves nothing about another (kb-connection-types).

  2. Run tailscale ping cloud-1 and let it finish. By default the command stops after ten pings or once a direct, non-DERP path has been established, whichever comes first. It runs all ten, and every pong reports via DERP(sin) at roughly 240 ms. This rules out a transient blip: direct path establishment to this specific peer is failing continuously, which is exactly the condition where Tailscale falls back to relaying (kb-derp).

  3. tailscale netcheck on node-a. UDP true, a public IPv4 mapping, nearest DERP New York City at 18 ms, Singapore at 242 ms. This rules out the laptop side: node-a can do UDP and is nowhere near Singapore. The DERP region in the status line belongs to the far end.

  4. tailscale netcheck on cloud-1 (over the tailnet, which still works, just slowly):

    Report:
        * Time: 2026-08-10 22:11:03.482119+08:00
        * UDP: true
        * IPv4: yes, 198.51.100.190:61712
        * IPv6: no, but OS has support
        * MappingVariesByDestIP: true
        * PortMapping:
        * Nearest DERP: Singapore
        * DERP latency:
            - sin: 3.9ms    (Singapore)
            - hkg: 38.1ms   (Hong Kong)
            - tok: 71.4ms   (Tokyo)

    MappingVariesByDestIP: true means the office edge is a hard NAT that gives every destination a different source mapping, and the empty PortMapping line means no NAT-PMP or UPnP escape hatch exists. This rules out a DERP outage or a Tailscale infrastructure problem: relaying here is the documented, expected fallback when a direct connection is not possible (kb-derp). The office firewall is the mechanism.

  5. Throughput cross-check. iperf3 from node-a to cloud-1 over the tailnet reads about 2 Mbps, matching the exit node experience exactly. iperf3 from lab-vm-1, sitting on the same office LAN as cloud-1, to an internet target reads several hundred Mbps. This rules out hypothesis A (host or provider throttle) and hypothesis C (DNS): the ceiling follows the tailnet path to cloud-1, not the host or name resolution.

Root cause

Routing all traffic through an exit node means you are “effectively using default routes (0.0.0.0/0, ::/0)” pointed at that peer, “similar to how you would if you were using a typical VPN” (kb-exit-nodes). That is the whole feature. There is no separate exit node transport: the traffic rides the exact same WireGuard peer connection that tailscale status shows for cloud-1, chosen by the same NAT traversal machinery covered in Module 03. So the rule is brutal and simple: if the path to the exit node is relayed, then ALL internet traffic is relayed.

Here the office edge in Singapore is a hard NAT with no port mapping protocol, so node-a and cloud-1 never establish a direct UDP path and fall back to DERP (kb-derp). The geometry then doubles the damage: node-a delivers packets via the Singapore DERP region, so a request for a US website travels US to Singapore relay, Singapore relay to the office, office back out across the Pacific to the US site, and the reply retraces all of it. Relays are a correctness fallback, not a performance path: “direct connections usually provide the lowest latency and highest throughput, while relayed connections are a fallback” (kb-connection-types). At 240 ms of added RTT on a shared relay, 2 Mbps is a normal result. This is Module 07 routing behavior explained by Module 03 path selection.

Fix and prevention

Immediate. Make the direct path possible from the exit node’s side: allow inbound UDP to cloud-1’s WireGuard port on the office firewall, or enable NAT-PMP on the edge so PortMapping stops coming back empty. Verify with tailscale ping cloud-1 until pongs report a real ip:port instead of via DERP(sin), then re-run the throughput test through the exit node.

Durable. If the office edge cannot be opened, deploy a Tailscale peer relay on lab-vm-1 in the same office (kb-peer-relays). Peer relays reached general availability in February 2026 (changelog) and require “Tailscale version 1.86 or later” on the relay device and on the devices using it (kb-peer-relays). Use tailscale set with the --relay-server-port option to pick the UDP port, for example tailscale set --relay-server-port=40000, open that single UDP port, and add the grant:

{
  "grants": [{
    "src": ["*"],
    "dst": ["tag:exit"],
    "app": {"tailscale.com/cap/relay": []}
  }]
}

Clients try direct first, then peer relays, then DERP (kb-derp), and a peer relay in the same building as the exit node removes the trans-Pacific detour. Confirm with tailscale status | grep peer-relay (kb-peer-relays). Finally, ask what the exit node is for: if the goal was privacy rather than a Singapore egress IP, an exit node in the Customer’s own region ends the mismatch entirely.

The handoff package

Not escalated (resolved in support), but as filed it would read:

The trap

The weak investigation accepts the Customer’s framing: “tailnet is fast, therefore the exit node machine is broken,” and rebuilds cloud-1. The rebuild changes nothing, because the office NAT is untouched, and now the ticket carries a failed fix and a Customer who watched hours of work produce zero improvement. The tell was sitting in the very first tailscale status: two peers, two different path types. Per-peer path inspection costs ten seconds. Skipping it costs a rebuild, and it also misses the real lesson of Module 03: fast traffic to one peer is never evidence about the path to another.

Sources

  1. Exit nodes (route all traffic) checked 2026-08-10
  2. DERP servers checked 2026-08-10
  3. Tailscale Peer Relays checked 2026-08-10
  4. Connection types checked 2026-08-10
  5. What firewall ports should I open to use Tailscale? checked 2026-08-10
  6. Tailscale changelog checked 2026-08-10

All drills