WireGuard vs Tailscale: Which One to Run
Tailscale runs on WireGuard, so the real choice is about the control plane: key distribution, NAT traversal, relays, identity, and what fails without them.
The framing of this question is usually wrong. Tailscale is not an alternative to WireGuard; it uses WireGuard as its data plane. Both move packets with the same Noise handshake, the same Curve25519 keys, and the same ChaCha20-Poly1305 encryption. The comparison is entirely about the layer WireGuard deliberately omits: something that decides which keys exist, which peers may talk, and how they find each other through NAT.
That layer is called a control plane. WireGuard has none by design, and the whole argument comes down to whether you want to be it.
The short answer
Run plain WireGuard when the peers are few and mostly fixed, at least one end has a stable public address, and having no external dependency is a requirement rather than a preference.
Run Tailscale or a similar overlay when devices are numerous, roam constantly, or sit behind carrier grade NAT on both sides, and when per-user access rules matter more than owning every moving part.
Run Headscale when you want the second experience with the coordination server on your own infrastructure.
Side by side
| Plain WireGuard | Tailscale | |
|---|---|---|
| Data plane | Kernel implementation on Linux, in-tree since 5.6 | The same protocol via a bundled userspace implementation |
| Key distribution | Manual; every public key copied to every peer | Automatic through the coordination server |
| Peer discovery | None; each peer needs a reachable Endpoint | Automatic, with per-node addresses assigned for you |
| NAT traversal | None beyond endpoint roaming and keepalives | STUN, birthday-paradox probing, port mapping, hole punching |
| Fallback when direct fails | None; you build a public hub yourself | Encrypted relays that carry traffic without holding keys |
| Access control | AllowedIPs per peer, edited on every device | Central policy file evaluated for the whole network |
| Identity | The public key is the only identity | SSO through an existing identity provider |
| DNS | Manual, or the wg-quick DNS line | Names assigned and resolved automatically |
| External dependency | None | A coordination service you do not operate |
| Cost | None | Free tier for personal use, paid tiers above it |
| Config growth for N peers | O(N) blocks per node in a full mesh | Unchanged; peers are enrolled, not configured |
That last row is the one that decides most real deployments. A full mesh of N peers needs N(N-1)/2 tunnels, and each node’s config lists every other node. Ten peers is 45 tunnels and ten configs that all change when one key rotates. The mesh designer shows this growth directly: move the peer count and watch the tunnel total climb.
What the control plane actually does
Four jobs, and it is worth separating them because you may only need some.
Key distribution. Each Tailscale node generates its own keypair locally. The private key never leaves the device; only the public key is registered. The coordination server then tells each node which public keys its peers hold, which is the mechanical equivalent of you pasting [Peer] blocks into config files, done continuously and automatically. Rotating a key becomes an operation on one node instead of an edit on all of them.
NAT traversal. This is the part plain WireGuard genuinely does not do. WireGuard is a UDP socket with endpoint roaming: a peer’s stored address updates to the source of the most recent authenticated packet, and PersistentKeepalive holds a NAT mapping open from the inside. That is enough when one end is publicly reachable. When both ends sit behind NAT, particularly the carrier grade kind that gives no inbound port at all, plain WireGuard has no mechanism to open a path. Tailscale’s published description of its approach uses STUN to learn each node’s external address, probes ports where a NAT assigns them unpredictably, uses UPnP-IGD, NAT-PMP, and PCP where the router offers them, and coordinates simultaneous outbound packets from both sides so each opens a mapping the other can use.
A fallback path. When traversal fails, an overlay relays. Tailscale’s relays carry encrypted packets between two nodes that cannot reach each other directly. The relay never holds a node private key and cannot decrypt what it forwards, so the confidentiality argument is unchanged; what changes is latency and the fact that someone else’s server is now in your data path. Plain WireGuard’s equivalent is a small VPS acting as a hub, which you provision, secure, patch, and pay for.
Identity and policy. Tailscale ties nodes to accounts in an identity provider and evaluates a central policy document to decide which node may reach which port on which other node. Plain WireGuard’s only identity is a public key, and its only access control is AllowedIPs, edited per interface. Answering “which human is this” requires a layer above WireGuard, never inside it.
Where plain WireGuard wins
No external dependency. Two peers with each other’s public keys will complete a handshake whether or not any other service on earth is running. Nothing to sign into, no account to lose, no vendor to change terms. For a site to site link between two buildings, this is the entire argument and it is decisive.
Kernel data plane. On Linux the in-tree module handles packets in kernel space with no context switching per packet. The Tailscale client ships its own userspace WireGuard implementation for portability across platforms, which trades some throughput for consistency. On a gigabit link between two well provisioned endpoints most people will not notice; on a small router pushing near line rate, they will.
A surface you can read. The WireGuard whitepaper puts the Linux implementation at under 4,000 lines, excluding the cryptographic primitives. A wg0.conf is a dozen lines. Reviewing exactly what is trusted takes minutes, and the auditability is often the reason a security team will approve a tunnel at all.
Cost that stays at zero. No per-user pricing, no plan tiers, no seat count to explain at renewal.
Where plain WireGuard hurts
Configuration that grows quadratically. Covered above, and it is the reason mesh topologies collapse into hub and spoke in practice.
No revocation. Keys never expire. Removing a device means deleting its [Peer] block from every interface that trusted it, on every device, by hand. Miss one and access persists silently.
Both ends behind CGNAT. No amount of configuration fixes this. The options are a public relay you run, a forwarded port, native IPv6, or an overlay.
Nothing tells you what is wrong. WireGuard is silent by design. Failure looks like an absent handshake line, and the diagnosis is yours. The workflow in the fundamentals article and the MTU calculation guide exists because that silence is the normal experience.
Where Tailscale hurts
A dependency you do not operate. The coordination service is the thing you traded away independence for. Established peer connections are designed to keep working if it becomes unreachable, but enrolling a new device, changing policy, or re-authenticating after key expiry all need it. Decide in advance whether an outage there is an inconvenience or an incident.
Metadata visibility. Payloads stay end to end encrypted, including across relays. Node names, public keys, addresses, and the shape of the network are known to the service, because coordinating the network is exactly what it does.
A moving target. Client, control plane, and plan terms all change on someone else’s schedule. Plain WireGuard’s config from four years ago still works.
Userspace performance ceiling. Real but frequently overstated. It matters on constrained hardware and high throughput links, not on a laptop connecting to a file server.
The middle option: Headscale
Headscale is an open source implementation of the Tailscale coordination server. Official Tailscale clients connect to it, so devices get automatic key distribution, NAT traversal, and node addressing, while the control plane runs on hardware you own. The trade is honest: you now operate the control plane, including its availability, backups, and upgrades, and you are tracking an independent project’s compatibility with a client you do not control. For an operator who already runs services and specifically objects to the third-party dependency rather than to the concept of a control plane, it is the closest thing to having both.
Choosing, concretely
- Two offices, static IPs, one tunnel. Plain WireGuard. A control plane adds nothing.
- A homelab and three of your own devices. Plain WireGuard hub and spoke. One VPS or router terminates, everything else dials in, keepalives keep NAT open. The Ubuntu server and client setup is that build.
- A dozen laptops that roam between offices, homes, and cellular. Tailscale, or Headscale if the dependency is unacceptable. Manual key distribution across roaming NAT is where plain WireGuard stops being cheaper than the subscription.
- Contractors who need one internal service. Overlay. Per-user policy and revocation on a schedule are the whole job, and
AllowedIPsdoes not do them. - Air gapped, regulated, or audit heavy. Plain WireGuard. Auditing a few thousand lines and a text config beats explaining a third-party control plane to an auditor.
The two also coexist. Plenty of networks run plain WireGuard for fixed site to site links, where the tunnel must survive anything, and an overlay for the roaming device fleet, where the operational cost of doing it by hand is the actual expense.
Where to go next
- WireGuard keys, AllowedIPs and NAT traversal covers the mechanics both options are built on, and why a control plane exists at all.
- The WireGuard MTU calculator works out the tunnel overhead that decides whether a hub-and-spoke build fragments before it is even in service.
- OPNsenseLab is the place to look if the hub in a plain-WireGuard build will be an OPNsense firewall rather than a VPS, since that is where the tunnel interface and its routing get configured.
- pfSenseLab covers the same job on pfSense, including the NAT and port-forward rules that decide whether an inbound handshake reaches your endpoint at all.
Sources
Related
WireGuard MTU Calculator and Fragmentation Fix
Work out the right WireGuard MTU from your path MTU, understand the 60 and 80 byte overhead, measure the real ceiling, and clamp TCP MSS correctly.
WireGuard Setup on Ubuntu: Server and Client
A config-first WireGuard install on Ubuntu: key generation, wg0.conf for server and client, forwarding, firewall rules, and adding peers without downtime.
WireGuard Explained: Keys, AllowedIPs, and NAT Traversal
How WireGuard really works: the static key handshake, what AllowedIPs controls, PersistentKeepalive and NAT, MTU math, and how it compares to OpenVPN.