Tailscale Architecture
How Tailscale achieves direct, encrypted connections through NATs
Architecture Overview
Tailscale's architecture is split into two completely separate planes: a control plane (coordination server) that handles identity, key distribution, and policy — and a data plane (WireGuard mesh) that carries actual traffic peer-to-peer. The coordination server never sees your data.
The Key Architectural Decision
Traditional VPNs (OpenVPN, IPsec concentrators) route all traffic through a central server. This creates a bandwidth bottleneck, a single point of failure, and adds latency for every packet. Tailscale inverts this model:
- Control plane: Centralized (coordination server). Handles authentication, key exchange, ACL distribution, endpoint discovery. Low-bandwidth, stateless for data.
- Data plane: Fully decentralized (WireGuard mesh). Every node connects directly to every other node it needs to communicate with. No central server in the data path.
- All traffic through VPN concentrator
- Bandwidth bottleneck at server
- Latency: A → Server → B (extra hop always)
- Server failure = total outage
- Server sees all traffic (even if encrypted)
- Traffic goes directly A → B
- No central bandwidth bottleneck
- Optimal latency (shortest path)
- Coord server down = existing connections persist
- Coordination server never sees data traffic
Note
Resilience under control plane outage: If the coordination server goes down, existing WireGuard tunnels continue working because they already have each other's keys and endpoints. You can't add new nodes or update ACLs, but existing connectivity is unaffected. This is a direct benefit of separating control and data planes.
Node Registration & Key Distribution
- Key generation: On first run, the Tailscale client generates a WireGuard keypair (Curve25519). The private key never leaves the device.
- Authentication: The user authenticates via an OAuth/OIDC provider (Google, Microsoft, GitHub, Okta, etc.). This binds the device to a user identity in the tailnet.
- Registration: The client sends its WireGuard public key, and endpoint information to the coordination server. The server stores this and assigns the node a stable 100.x.y.z IP address.
- Peer distribution: The coordination server pushes authorized peer information (public keys, endpoints, allowed IPs) to each node based on ACL policy. Each node only receives info about peers it's allowed to communicate with.
- WireGuard configuration: The Tailscale client dynamically configures the local WireGuard interface with the received peer information. No manual WireGuard config files needed.
Tip
No manual key management: Compare this to raw WireGuard, where you manually exchange public keys between every pair of peers and update config files. Tailscale automates this entirely — the coordination server is essentially a WireGuard key distribution service paired with an identity provider.
Connection Establishment Flow
When Node A needs to reach Node B, Tailscale's connection engine (derp/derphttp, wgengine, magicsock) executes a multi-stage process to find the best path.
Key Lookup
Get B's WireGuard pubkey from coordination server
STUN Discovery
Both peers discover their public endpoints
Endpoint Exchange
Share endpoints via coordination server
Direct Attempt
UDP hole punch to each other's endpoints
Fallback: DERP
If direct fails, relay via DERP
Detailed Connection Sequence
- Both nodes know each other's WireGuard public keys (distributed by coordination server at registration time). They don't need to fetch keys on-demand — they already have them.
- STUN discovery: Both nodes periodically send STUN Binding Requests to Tailscale's STUN servers (co-located with DERP servers) to discover their public
IP:port. These results are sent to the coordination server. - Endpoint exchange: The coordination server shares each node's discovered endpoints (possibly multiple — one per interface, IPv4 and IPv6) with authorized peers.
- Direct connection attempt: Both nodes simultaneously send WireGuard handshake packets to each other's public endpoints. This is UDP hole punching — the outbound packets create NAT mappings that allow the peer's packets through.
- Path optimization: Tailscale also tries UPnP, NAT-PMP, and PCP to request explicit port mappings from the NAT gateway. If the gateway supports these, it can allocate a stable mapping without relying on hole punching.
- DERP fallback: If direct connectivity fails after a timeout (a few seconds), traffic immediately starts flowing via the nearest DERP relay while direct path attempts continue in the background. Many connections start on DERP and upgrade to direct seconds later.
Note
The "magicsock" abstraction: Tailscale's magicsock package wraps the WireGuard socket and transparently switches between direct UDP, UPnP-mapped paths, and DERP relay without the upper layers (WireGuard) knowing. From WireGuard's perspective, it's always talking to a single UDP socket — magicsock handles all the NAT traversal complexity underneath.
DERP (Designated Encrypted Relay for Packets)
DERP is Tailscale's answer to TURN. But it's designed very differently from traditional TURN servers, with several architectural decisions that make it more practical for a WireGuard-based mesh.
DERP vs Traditional TURN
| Aspect | TURN | DERP |
|---|---|---|
| Transport | UDP primary, TCP/TLS optional | HTTPS (TCP/TLS on port 443) primary |
| Protocol | TURN protocol (complex, stateful allocations) | Simple custom protocol over WebSocket-like framing |
| Encryption | Relay can see payloads (unless DTLS/SRTP) | Payloads are WireGuard-encrypted end-to-end; DERP relays opaque ciphertext |
| Firewall traversal | UDP often blocked; TCP fallback available | Always HTTPS — works through virtually any firewall/proxy |
| Authentication | Credentials-based (TURN username/password) | Tailscale node key (tied to identity) |
Warning
Critical point: DERP is not a VPN concentrator. It cannot decrypt or inspect your traffic. All data passing through DERP is WireGuard-encrypted with keys that only the two communicating peers possess. DERP is a dumb packet forwarder — it sees opaque encrypted blobs and routes them by destination node key.
DERP Architecture
Why HTTPS on Port 443?
This is a deliberately pragmatic design choice. Almost every network on earth allows outbound HTTPS (TCP 443). Corporate proxies, hotel WiFi captive portals, airplane WiFi, restrictive firewalls — they all pass HTTPS. By running DERP over HTTPS:
- Works behind HTTP proxies (CONNECT method)
- Passes DPI (deep packet inspection) that blocks VPN protocols
- No special firewall rules needed — looks like normal web traffic
- Survives networks that block all UDP (DERP is TCP-only)
Global DERP Map
Tailscale operates DERP servers worldwide. Each node connects to its nearest DERP server, and DERP servers can relay to each other if two nodes are closest to different DERP regions.
$ tailscale netcheck
Report:
* UDP: true
* IPv4: yes, 203.0.113.50:41641
* IPv6: yes
* MappingVariesByDestIP: false
* Nearest DERP: San Francisco
* DERP latency:
- sf: 2.1ms (San Francisco)
- lax: 5.3ms (Los Angeles)
- sea: 12.1ms (Seattle)
- chi: 32.4ms (Chicago)
- nyc: 61.2ms (New York)
- fra: 142.5ms (Frankfurt)
- sin: 168.3ms (Singapore)
- syd: 179.8ms (Sydney)
Tip
Self-hosted DERP: You can run your own DERP server (cmd/derper in the Tailscale repo) and add it to your tailnet's DERP map. Useful if you want relay traffic to stay on your infrastructure, or if your nodes are in a region far from Tailscale's DERP servers.
Direct vs Relayed — Checking Connection Status
$ tailscale status
100.64.0.1 myphone user@ linux active; direct 203.0.113.50:41641, tx 15424 rx 9872
100.64.0.2 workstation user@ linux active; direct 198.51.100.5:41641, tx 892341 rx 445123
100.64.0.3 cloud-vm user@ linux active; relay "sf", tx 4521 rx 2341
100.64.0.4 homeserver user@ linux idle
Reading tailscale status Output
| Field | Meaning |
|---|---|
direct 203.0.113.50:41641 |
Direct WireGuard connection established. Traffic goes peer-to-peer via this endpoint. Best case. |
relay "sf" |
Traffic is being relayed through the "sf" (San Francisco) DERP server. Direct connection failed — possibly Symmetric NAT or UDP blocked. |
idle |
No recent traffic. WireGuard handshake may have expired. Will re-establish on next packet. |
tx / rx |
Bytes transmitted and received to/from this peer. |
Tip
Upgrade in progress: Connections often start as relay and upgrade to direct within seconds. If you see relay persistently, run tailscale ping <host> to see if direct connectivity eventually succeeds. If it stays on relay, check tailscale netcheck on both ends — one of them likely has a Symmetric NAT or UDP blocking.
Tailscale vs Raw WireGuard vs Headscale
| Aspect | Raw WireGuard | Tailscale | Headscale |
|---|---|---|---|
| Key distribution | Manual (copy pubkeys between configs) | Automatic (coordination server) | Automatic (self-hosted coordination) |
| NAT traversal | None (need public IP or port forward) | Full (STUN + hole punch + DERP relay) | Full (uses Tailscale client, same traversal) |
| ACLs | Manual iptables/nftables | Policy-as-code via coordination server | Same ACL format, self-managed |
| DNS | Manual /etc/hosts or DNS server | MagicDNS (automatic) | MagicDNS (automatic) |
| Control plane | N/A (no control plane) | Tailscale SaaS (proprietary) | Self-hosted (open source) |
| Scaling | O(n²) config complexity | Automatic mesh, scales to thousands | Same, limited by self-hosted capacity |
Note
Headscale: An open-source, self-hosted implementation of the Tailscale coordination server. It implements the same coordination protocol, so standard Tailscale clients can connect to it. You get the same NAT traversal and mesh networking without depending on Tailscale's SaaS. The trade-off is you manage the server, backups, and availability yourself.