Tailscale spent years on the obvious throughput work: TCP on Linux, wireguard-go past 10 Gb/s, segmentation offload for UDP traffic. The next round attacks the unglamorous parts — copies, queue depth, and a single-lane packet pipeline — and the numbers came from attacking memory overhead first.
What actually changed:
- Most packets are ~1 KiB, but the kernel path (GRO) obliges Tailscale to accept up to 64 KiB, and wireguard-go only offered one 64 KiB buffer to unpack into — so every small packet got copied into its own oversized allocation
- On Linux and Android it now marks where each packet starts and ends inside the single large read instead of copying it out; small packets stay small, many share one allocation, and that alone bought roughly 5% in many configurations
- Packet queues were shortened after testing showed most of their depth went unused — less waiting, less memory
- The freed memory was handed to subnet routers and app connectors, which had been processing every stream through one ordered single-thread pipeline because a receiving app must never see its own packets reordered
- With headroom available, that became a multi-queue system: several independent lanes, sized to the machine rather than the peer count, each stream pinned to one lane so ordering holds while lanes run on different cores
writevlets it describe scattered packet data to the kernel in one operation instead of copying and combining pieces first — fewer copies, fewer writes- Netmap caching is the one that changes behaviour rather than throughput: a client stores its network map on disk, so when the control plane is unreachable — bad Wi-Fi, filtered hotel networks — the device can still establish peer connections and start working, then refresh when it gets through
The interesting part is the shape of the argument. Performance work at this maturity is not algorithm work; it is deciding what memory you were holding out of habit and then spending the savings where contention actually lives. The released caveats are refreshingly plain: netmap caching needs persistent disk, requires one prior successful connection, can generate heavy disk traffic on very large tailnets, and is a bad idea on wear-sensitive storage like SD cards.
Netmap caching is also the more broadly useful idea. It converts “control plane unreachable” from a hard failure into a degraded-but-working mode, which is the same trade successful offline-first designs make everywhere outside networking.
Rollout is staged: buffer changes and netmap caching land in v1.104, multi-queue in a release after it.