Tailscale vs WireGuard vs ZeroTier: VPN for Self-Hosters in 2026


Tailscale vs WireGuard vs ZeroTier: VPN for Self-Hosters in 2026

You have a home server running Nextcloud, Jellyfin, Home Assistant, and a dozen other services. They work perfectly on your local network. Now you leave the house and everything is unreachable.

The traditional solution — port forwarding through your router and exposing services to the public internet — works, but it means your services are visible to the entire internet. Every port scan hits them. Every bot tries default credentials against them. You are one misconfigured service away from handing a stranger access to your entire home network.

A VPN solves this by creating an encrypted tunnel between your devices and your home network. Your services stay invisible to the internet, but you can reach them from anywhere as if you were sitting on your couch.

In 2026, three VPN solutions dominate the self-hosting space: WireGuard, the protocol that changed everything; Tailscale, the company that made WireGuard effortless; and ZeroTier, the peer-to-peer mesh network that predates both and takes a fundamentally different approach.

This guide compares all three with setup instructions, performance data, and honest recommendations based on what you are actually trying to do.

Table of Contents

TL;DR

  • WireGuard is best for: users who want maximum control, zero dependencies on third-party services, and the highest possible performance. You manage everything yourself — key distribution, routing, NAT traversal. Excellent once configured, but the setup is manual.
  • Tailscale is best for: everyone who wants WireGuard’s performance without WireGuard’s configuration complexity. Zero-config NAT traversal, automatic key rotation, excellent ACLs, works on every platform. The free tier (3 users, 100 devices) covers most self-hosters. The tradeoff is that Tailscale’s coordination server sees your network metadata (not your traffic).
  • ZeroTier is best for: users who need a flat Layer 2 network across multiple sites, or who want to self-host the entire stack including the controller. Its peer-to-peer architecture is elegant, and it works in scenarios where WireGuard struggles (heavy NAT, cellular networks).
  • If you just want something that works: install Tailscale on every device, approve them in the admin console, and you are done. Time from zero to a working mesh VPN: about five minutes.

Quick Comparison Table

FeatureWireGuardTailscaleZeroTier
TypeVPN protocolMesh VPN (uses WireGuard)Mesh VPN (custom protocol)
ArchitecturePoint-to-point / hub-spokeMesh (peer-to-peer)Mesh (peer-to-peer)
Network LayerLayer 3 (IP)Layer 3 (IP)Layer 2 (Ethernet) / Layer 3
EncryptionChaCha20, Poly1305, Curve25519WireGuard (same)ChaCha20, Poly1305, Curve25519
ProtocolUDPUDP (WireGuard)UDP (custom)
NAT TraversalManual (requires port forward)Automatic (DERP relays)Automatic (root servers)
Setup ComplexityHighVery LowLow
Key ManagementManualAutomaticAutomatic
ACLsiptables / nftablesBuilt-in (JSON policy)Built-in (flow rules)
DNSManual / third-partyMagicDNS (built-in)DNS push (basic)
Exit Node (full tunnel)Manual configOne clickVia routing rules
Speed (typical)~900 Mbps~800 Mbps~500 Mbps
Latency Overhead~0.5ms~0.5-1ms~1-3ms
Open SourceYes (GPLv2, kernel module)Client: BSD-3. Server: ProprietaryClient: BSL 1.1. Server: Proprietary
Self-Hosted Control PlaneN/A (no control plane)Headscale (community)ZeroTier Controller (official)
Free TierFree (it is a protocol)3 users, 100 devices25 devices
Paid PlansN/AFrom $6/user/monthFrom $5/month (50 devices)
PlatformsLinux, Windows, macOS, iOS, Android, FreeBSDAll of the above + ChromeOS, tvOSAll of the above
Kernel IntegrationLinux kernel module (fastest)Userspace (Go)Userspace (C++)

Understanding the Landscape

Before comparing these three, it helps to understand that they are not all the same thing.

WireGuard is a VPN protocol. It is built into the Linux kernel and handles encrypted tunneling between two endpoints. It does not handle service discovery, key distribution, NAT traversal, or access control. It is a building block, not a complete solution.

Tailscale is a mesh VPN product built on top of WireGuard. It adds a coordination server that handles key exchange, NAT traversal, DNS, and access control. The data plane (your actual traffic) goes directly between devices using WireGuard. The control plane (who can connect to what) goes through Tailscale’s servers.

ZeroTier is a mesh VPN product with its own custom protocol. It creates virtual Ethernet networks that span the internet, allowing devices to communicate as if they were on the same LAN. It predates WireGuard and takes a fundamentally different architectural approach.

The key distinction: WireGuard is infrastructure you build on. Tailscale and ZeroTier are products you use. This difference shapes everything from setup complexity to ongoing maintenance.

WireGuard: The Protocol That Changed Everything

WireGuard was created by Jason Donenfeld and merged into the Linux kernel in March 2020 (version 5.6). Before WireGuard, VPN meant OpenVPN (slow, complex, 70,000 lines of code) or IPSec (arcane configuration, brittle). WireGuard was roughly 4,000 lines of code, used modern cryptography, and was measurably faster than anything else available.

How WireGuard Works

WireGuard creates a virtual network interface (like wg0) on each machine. Each peer has a public/private key pair. You configure each peer with the public keys of the peers it should communicate with, along with allowed IP ranges.

When a packet arrives at the WireGuard interface, the kernel encrypts it, wraps it in a UDP packet, and sends it to the peer’s endpoint (IP address and port). The receiving peer decrypts it and delivers it to the local network stack. The entire handshake uses Noise Protocol Framework, and a new session is established in a single round trip.

There is no concept of “connecting” or “disconnecting.” WireGuard interfaces are always up. If a peer is reachable, packets flow. If it is not reachable, packets are silently dropped. This stateless design is elegant but means WireGuard has no built-in mechanism to tell you when a peer goes offline.

WireGuard Setup Guide

Server Side (your home server, Ubuntu/Debian)

# Install WireGuard
sudo apt update && sudo apt install wireguard

# Generate server keys
wg genkey | tee /etc/wireguard/server_private.key | wg pubkey > /etc/wireguard/server_public.key
chmod 600 /etc/wireguard/server_private.key

# Generate client keys (do this for each device)
wg genkey | tee /etc/wireguard/client1_private.key | wg pubkey > /etc/wireguard/client1_public.key

Server Configuration

# /etc/wireguard/wg0.conf
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = <server_private_key>

# Enable IP forwarding and NAT (so clients can access your LAN)
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

# Client 1 (laptop)
[Peer]
PublicKey = <client1_public_key>
AllowedIPs = 10.0.0.2/32

# Client 2 (phone)
[Peer]
PublicKey = <client2_public_key>
AllowedIPs = 10.0.0.3/32
# Enable IP forwarding
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

# Start WireGuard
sudo systemctl enable --now wg-quick@wg0

# Open the port on your firewall
sudo ufw allow 51820/udp

You also need to forward UDP port 51820 from your router to your server. This is the main operational hurdle with WireGuard: it requires a port forward, which means you need a public IP address (or at least a predictable one) and router access.

Client Configuration

# /etc/wireguard/wg0.conf (on client)
[Interface]
Address = 10.0.0.2/24
PrivateKey = <client1_private_key>
DNS = 10.0.0.1  # Optional: use your server's DNS (e.g., Pi-hole or AdGuard Home)

[Peer]
PublicKey = <server_public_key>
Endpoint = your-public-ip:51820
AllowedIPs = 10.0.0.0/24, 192.168.1.0/24  # VPN subnet + your home LAN
PersistentKeepalive = 25

The AllowedIPs field is crucial. Setting it to 0.0.0.0/0 routes all traffic through the VPN (full tunnel). Setting it to specific subnets only routes traffic destined for those networks (split tunnel). For self-hosting, you usually want split tunnel so that your regular internet traffic does not route through your home connection.

Client Configuration for Mobile (QR Code)

The easiest way to configure mobile devices is to generate a QR code:

sudo apt install qrencode

# Create client config
cat > /tmp/client-phone.conf << EOF
[Interface]
Address = 10.0.0.3/24
PrivateKey = <client2_private_key>
DNS = 10.0.0.1

[Peer]
PublicKey = <server_public_key>
Endpoint = your-public-ip:51820
AllowedIPs = 10.0.0.0/24, 192.168.1.0/24
PersistentKeepalive = 25
EOF

# Generate QR code
qrencode -t ansiutf8 < /tmp/client-phone.conf

# Clean up
rm /tmp/client-phone.conf

Open the WireGuard app on your phone, tap “Add Tunnel,” scan the QR code, and you are connected.

WireGuard Pros and Cons

Pros:

  • Fastest VPN protocol available — kernel-level implementation with minimal overhead
  • Built into the Linux kernel, no additional software needed on the server
  • Extremely simple protocol design (4,000 lines of code) means a small attack surface
  • No dependency on any third-party service or coordination server
  • Works on every major platform including routers (OpenWrt, pfSense, OPNsense)
  • Completely free and open source (GPLv2)
  • Minimal resource usage — runs on a Raspberry Pi without breaking a sweat

Cons:

  • Manual key distribution — you generate and copy keys yourself
  • No built-in NAT traversal — requires a port forward or a publicly accessible endpoint
  • No automatic peer discovery — you must know the endpoint of every peer
  • No built-in DNS — you configure DNS separately
  • No access control beyond AllowedIPs — for fine-grained policies, you use iptables
  • Adding a new device means editing the server config and reloading
  • No built-in way to detect peer health or connectivity status
  • CGNAT (carrier-grade NAT) makes WireGuard inaccessible without a VPS relay

Tailscale: WireGuard Made Easy

Tailscale took WireGuard’s excellent protocol and wrapped it in a product that handles everything WireGuard does not: key management, NAT traversal, DNS, access control, and multi-device coordination. The result is a VPN that takes about 60 seconds to set up and just works.

How Tailscale Works

When you install Tailscale on a device and log in, the Tailscale client registers with the coordination server and exchanges public keys. The coordination server distributes keys to all your devices so they know how to reach each other.

The clever part is NAT traversal. Tailscale uses a technique called STUN to determine the NAT type of each device and establish direct peer-to-peer connections whenever possible. When direct connections fail (double NAT, symmetric NAT, restrictive firewalls), traffic routes through DERP (Designated Encrypted Relay for Packets) servers maintained by Tailscale.

Crucially, the coordination server never sees your traffic. It only handles key exchange and connection metadata. The actual data flows directly between your devices using WireGuard encryption, even when using DERP relays.

Tailscale Setup Guide

On Any Linux Server

# Install Tailscale (one-liner)
curl -fsSL https://tailscale.com/install.sh | sh

# Authenticate
sudo tailscale up

# This prints a URL -- open it in your browser to authenticate
# Your device appears in the Tailscale admin console immediately

That is it. Your server is now on your Tailscale network (called a “tailnet”) and has a stable IP address in the 100.x.x.x range.

On macOS, Windows, iOS, or Android

Download the Tailscale app from the respective app store. Sign in with the same account. Your device automatically connects to your tailnet and can reach every other device by IP or by name (via MagicDNS).

Enabling Subnet Routes (Access Your Entire LAN)

By default, Tailscale only makes the device itself accessible. To reach other devices on your home network through the Tailscale node, enable subnet routing:

# On your home server
sudo tailscale up --advertise-routes=192.168.1.0/24

# In the Tailscale admin console, approve the subnet route
# (this is a security feature -- routes must be explicitly approved)

Now any device on your tailnet can access 192.168.1.x addresses through your home server, even if those devices do not have Tailscale installed.

Using Your Server as an Exit Node

To route all internet traffic through your home server (useful when on public Wi-Fi):

# On your home server
sudo tailscale up --advertise-routes=192.168.1.0/24 --advertise-exit-node

# Approve the exit node in the admin console

# On your client device, enable the exit node
sudo tailscale up --exit-node=<server-tailscale-ip>

MagicDNS

Tailscale includes a DNS system called MagicDNS that gives every device a hostname. If your server is named “homelab,” you can reach it at homelab.your-tailnet-name.ts.net or simply homelab if MagicDNS is configured as your DNS resolver.

This integrates beautifully with self-hosted services. Instead of remembering IP addresses, you access homelab:8096 for Jellyfin, homelab:3000 for Grafana, and so on. Combined with a reverse proxy, you can use media.homelab.your-tailnet-name.ts.net for clean URLs.

Tailscale with Docker

# Run Tailscale as a sidecar container
services:
  tailscale:
    image: tailscale/tailscale:latest
    container_name: tailscale
    hostname: homelab
    environment:
      - TS_AUTHKEY=tskey-auth-xxxxx  # Generate in admin console
      - TS_STATE_DIR=/var/lib/tailscale
      - TS_EXTRA_ARGS=--advertise-routes=192.168.1.0/24
    volumes:
      - tailscale-state:/var/lib/tailscale
      - /dev/net/tun:/dev/net/tun
    cap_add:
      - net_admin
      - sys_module
    restart: unless-stopped

volumes:
  tailscale-state:

Tailscale Pros and Cons

Pros:

  • Setup takes under 5 minutes, no networking knowledge required
  • NAT traversal works in virtually every network environment, including CGNAT
  • MagicDNS provides automatic DNS for all devices on the network
  • Excellent ACL system with JSON policies (covered below)
  • Taildrop for file sharing between devices
  • SSH support (Tailscale SSH) eliminates the need for SSH key management
  • Free tier covers 3 users and 100 devices — more than enough for most self-hosters
  • Funnel feature can expose services to the internet through Tailscale’s infrastructure
  • Active development with frequent feature releases

Cons:

  • Coordination server is proprietary and hosted by Tailscale (metadata concern)
  • Slightly slower than raw WireGuard due to userspace implementation
  • If Tailscale’s infrastructure goes down, new connections cannot be established (existing connections continue)
  • The free tier is limited to 3 users (was previously unlimited for personal use)
  • Tailscale Funnel routes traffic through their servers, adding latency
  • SSH logging through Tailscale means Tailscale can theoretically access session recordings
  • Vendor lock-in: your network topology depends on Tailscale’s service

ZeroTier: The Peer-to-Peer Mesh Network

ZeroTier was founded in 2011, years before WireGuard existed. It takes a different approach: instead of building on an existing VPN protocol, ZeroTier created its own virtual network layer that operates at Layer 2 (Ethernet). This means ZeroTier can do things that WireGuard and Tailscale cannot, like bridging networks and supporting non-IP protocols.

How ZeroTier Works

ZeroTier creates a virtual network switch in software. Each device that joins a ZeroTier network gets a virtual network interface that behaves like a physical Ethernet connection to a switch. Devices can communicate using IP, but also using any protocol that works over Ethernet — multicast, mDNS, ARP, and so on.

The ZeroTier network has a 16-character network ID. When a device joins the network, it contacts ZeroTier’s root servers (called “moons” and “planets”) to perform key exchange and NAT traversal. Once a direct peer-to-peer connection is established, traffic flows directly between devices without going through any central server.

If direct connectivity is not possible, traffic relays through ZeroTier’s root servers. This is similar to Tailscale’s DERP relays but uses ZeroTier’s own protocol rather than WireGuard.

ZeroTier Setup Guide

Create a Network

  1. Go to my.zerotier.com and create an account
  2. Click “Create a Network” — you get a 16-character network ID
  3. Note the network ID (e.g., a09acf0233e4b070)

Install on Linux

# Install ZeroTier (one-liner)
curl -s https://install.zerotier.com | sudo bash

# Join the network
sudo zerotier-cli join a09acf0233e4b070

# Check status
sudo zerotier-cli status

# List networks
sudo zerotier-cli listnetworks

Authorize the Device

Back in the ZeroTier web console, your device appears under the “Members” tab. Check the “Auth” box to authorize it. You can also assign a static IP from the network’s managed range.

Install on Other Platforms

ZeroTier has native apps for macOS, Windows, iOS, and Android. Install the app, enter the network ID, and authorize the device in the web console.

Advanced Configuration: Bridge Mode

One of ZeroTier’s unique capabilities is bridging. You can bridge your ZeroTier virtual network with your physical LAN, allowing all devices on the ZeroTier network to access devices on your physical LAN — even devices that do not have ZeroTier installed.

# On your home server (the bridge)
# Enable IP forwarding
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

# Create bridge between ZeroTier interface and physical interface
# Identify your ZeroTier interface (usually starts with zt)
ip addr show | grep zt

# Add route on ZeroTier network (in the web console):
# Destination: 192.168.1.0/24
# Via: <ZeroTier IP of your bridge server>

# Enable bridging in the ZeroTier web console for this member
# Check "Allow Ethernet Bridging" under the member settings

# Add iptables rules for forwarding
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo iptables -A FORWARD -i zt+ -o eth0 -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o zt+ -m state --state RELATED,ESTABLISHED -j ACCEPT

ZeroTier with Docker

services:
  zerotier:
    image: zerotier/zerotier:latest
    container_name: zerotier
    devices:
      - /dev/net/tun
    network_mode: host
    cap_add:
      - NET_ADMIN
      - SYS_ADMIN
    volumes:
      - zerotier-data:/var/lib/zerotier-one
    environment:
      - ZEROTIER_ONE_NETWORK_IDS=a09acf0233e4b070
    restart: unless-stopped

volumes:
  zerotier-data:

ZeroTier Pros and Cons

Pros:

  • Layer 2 networking enables multicast, mDNS, and non-IP protocols
  • Bridging mode allows access to entire LANs through a single node
  • The controller can be fully self-hosted (ZeroTier Controller API)
  • 25 devices on the free tier
  • Works well in difficult NAT environments
  • Mature product with over a decade of development
  • Network segmentation with multiple isolated networks is easy
  • The 16-character network ID system is simple and memorable

Cons:

  • Slower than WireGuard and Tailscale due to userspace implementation and custom protocol
  • Higher latency, especially through relay servers
  • The web console UI is functional but dated compared to Tailscale’s polished interface
  • Flow rules (ACLs) are powerful but the syntax is complex and poorly documented
  • Less active community than Tailscale
  • Free tier limited to 25 devices (was more generous in the past)
  • Layer 2 networking introduces broadcast traffic overhead on large networks
  • Mobile apps are less polished than Tailscale’s
  • No equivalent to Tailscale’s MagicDNS (you manage DNS separately)

Setup Comparison: Getting Connected in Minutes

Let us quantify the setup effort for the most common self-hosting use case: connect a phone and a laptop to your home server.

StepWireGuardTailscaleZeroTier
Install on server1 min30 sec30 sec
Generate keys2 minAutomaticAutomatic
Configure server5 min0 (auto)0 (auto)
Port forward router3-10 minNot neededNot needed
Install on phone1 min1 min1 min
Configure phone3 min (QR code)30 sec (sign in)30 sec (enter network ID)
Install on laptop1 min1 min1 min
Configure laptop3 min30 sec (sign in)30 sec (enter network ID)
Authorize devicesN/A1 min (auto or manual)1 min (web console)
Enable LAN access5 min (iptables)1 min (subnet route)3 min (bridge mode)
Total time25-35 min5 min8 min
Networking knowledge requiredHighLowMedium

Performance Benchmarks

Performance testing was done using iperf3 between two machines on the same physical network, measuring the overhead added by each VPN. The baseline (no VPN) connection was a 1 Gbps Ethernet link.

MetricNo VPNWireGuardTailscaleZeroTier
Throughput (TCP)940 Mbps890 Mbps780 Mbps520 Mbps
Throughput (UDP)950 Mbps910 Mbps810 Mbps560 Mbps
Latency added0~0.3ms~0.5ms~1.5ms
Jitter0.02ms0.05ms0.08ms0.15ms
CPU usage (server)-~3%~8%~12%
Memory usage-~5 MB~40 MB~30 MB

WireGuard is fastest because it runs as a kernel module — packets never leave kernel space. Tailscale uses a userspace WireGuard implementation (wireguard-go), which adds context switches between kernel and userspace on every packet. ZeroTier uses its own protocol implementation in userspace, which adds additional overhead.

For typical self-hosting workloads (streaming media, syncing files, accessing web interfaces), the difference between 890 Mbps and 520 Mbps is irrelevant. You will not notice it. The difference matters for large file transfers between sites or real-time applications that are sensitive to latency, where WireGuard’s kernel implementation has a measurable advantage.

Performance over the Internet

When devices are separated by the internet (the actual use case for most self-hosters), the VPN overhead is dwarfed by internet latency and bandwidth limitations. On a 200 Mbps home connection:

MetricWireGuardTailscaleZeroTier
Throughput195 Mbps192 Mbps185 Mbps
Latency added~0.5ms~0.8ms~2ms

The differences shrink to the point of irrelevance. If your bottleneck is your ISP (and it almost certainly is), the VPN protocol matters far less than your upload speed.

Security and Encryption

All three use modern, well-audited cryptographic primitives:

AspectWireGuardTailscaleZeroTier
EncryptionChaCha20-Poly1305ChaCha20-Poly1305 (via WG)ChaCha20-Poly1305 (256-bit)
Key ExchangeCurve25519Curve25519 (via WG)Curve25519
AuthenticationPublic keyPublic key + OAuth/SSOPublic key + network ID
Forward SecrecyYes (per-session)Yes (via WG)Yes
Audit HistoryFormally verified (2018)Regular third-party auditsThird-party audit (2020)
Control Plane TrustNone (you run it)Tailscale’s serversZeroTier’s root servers

The most important security difference is the control plane:

  • WireGuard has no control plane. You distribute keys manually. There is no third party to trust or compromise.
  • Tailscale requires trusting their coordination server with your network metadata: which devices exist, their IP addresses, and which keys they hold. Tailscale cannot see your traffic (it is encrypted end-to-end with WireGuard), but they know your network topology.
  • ZeroTier requires trusting their root servers for peer discovery. Similar to Tailscale, they see metadata but not traffic content.

For most self-hosters, the metadata exposure of Tailscale and ZeroTier is an acceptable tradeoff for the convenience they provide. If it is not acceptable for your threat model, WireGuard (or Headscale, the self-hosted Tailscale control plane) is the answer.

Docker Socket Security Note

If you run Tailscale or ZeroTier in Docker containers, be aware that they typically require NET_ADMIN and SYS_MODULE capabilities, plus access to /dev/net/tun. These are elevated privileges. In a container environment, consider running the VPN client on the host and exposing it to containers via network configuration rather than giving containers elevated capabilities.

Access Control and Network Policies

WireGuard: DIY with iptables

WireGuard has no built-in access control. The AllowedIPs field controls which IP ranges a peer can send traffic from, but it does not restrict which services a peer can access. For fine-grained control, you use host-level firewalls:

# Allow client 10.0.0.2 to access only Jellyfin (port 8096) and Nextcloud (port 443)
sudo iptables -A FORWARD -i wg0 -s 10.0.0.2 -d 192.168.1.50 -p tcp --dport 8096 -j ACCEPT
sudo iptables -A FORWARD -i wg0 -s 10.0.0.2 -d 192.168.1.50 -p tcp --dport 443 -j ACCEPT
sudo iptables -A FORWARD -i wg0 -s 10.0.0.2 -j DROP

This works but is tedious and error-prone for complex setups.

Tailscale: ACLs as Code

Tailscale’s ACL system is one of its strongest features. Policies are defined in JSON (or HuJSON, which allows comments) and stored in the admin console or in a Git repository:

{
  "acls": [
    // Admins can access everything
    {"action": "accept", "src": ["group:admin"], "dst": ["*:*"]},

    // Family members can access media services only
    {"action": "accept", "src": ["group:family"], "dst": [
      "homelab:8096",   // Jellyfin
      "homelab:8080",   // Audiobookshelf
      "homelab:80",     // Nextcloud
      "homelab:443"     // Nextcloud HTTPS
    ]},

    // IoT devices cannot reach anything except the home server
    {"action": "accept", "src": ["tag:iot"], "dst": ["homelab:*"]},

    // Default deny
    {"action": "reject", "src": ["*"], "dst": ["*:*"]}
  ],

  "groups": {
    "group:admin": ["user@example.com"],
    "group:family": ["spouse@example.com", "kid@example.com"]
  },

  "tagOwners": {
    "tag:iot": ["group:admin"]
  }
}

This is declarative, auditable, and version-controllable. Changes take effect within seconds across all devices. Tailscale also supports device tags, user groups, and autoApprovers for subnet routes.

ZeroTier: Flow Rules

ZeroTier uses a domain-specific language for access control called “flow rules.” They are more powerful than Tailscale’s ACLs (because ZeroTier operates at Layer 2, rules can match on Ethernet frames, not just IP packets) but significantly harder to write:

# ZeroTier Flow Rules

# Drop all traffic by default
drop;

# Allow ICMP (ping)
accept ipprotocol 1;

# Allow established TCP connections
accept chr tcp_fin or chr tcp_rst or chr tcp_ack;

# Allow member 'homeserver' (by ZeroTier address) to accept all traffic
accept ipdest 10.147.17.1;

# Allow member 'laptop' to reach homeserver on ports 80, 443, 8096
accept ipsrc 10.147.17.2 and ipdest 10.147.17.1 and ipprotocol 6 and dport 80;
accept ipsrc 10.147.17.2 and ipdest 10.147.17.1 and ipprotocol 6 and dport 443;
accept ipsrc 10.147.17.2 and ipdest 10.147.17.1 and ipprotocol 6 and dport 8096;

The rule syntax is powerful but verbose, poorly documented, and easy to get wrong. For simple setups, it works fine. For complex multi-user environments, Tailscale’s ACLs are significantly easier to manage.

Pricing and Licensing

PlanWireGuardTailscaleZeroTier
FreeFree forever (kernel module)3 users, 100 devices25 devices
PersonalN/A$6/user/month (starts at 5 users)$5/month (50 devices)
BusinessN/A$18/user/month$49/month (unlimited)
EnterpriseN/ACustom pricingCustom pricing
Self-Hosted OptionN/A (no server)Headscale (free, community)Controller API (free, official)

The real cost comparison: WireGuard is free but costs your time to set up and maintain. Tailscale’s free tier covers most self-hosters with 3 users and 100 devices. ZeroTier’s 25-device limit might be restrictive if you have many IoT devices or containers on the network.

For families, the 3-user limit on Tailscale’s free tier means you, a partner, and one other person. If you have more family members who need access, you either pay for the Personal plan or use Headscale.

Self-Hosted Control Plane Options

Headscale (Tailscale Alternative)

Headscale is an open-source, self-hosted implementation of the Tailscale coordination server. It is written in Go and supports most of Tailscale’s features, including ACLs, DNS, and subnet routing.

# docker-compose.yml for Headscale
services:
  headscale:
    image: headscale/headscale:0.23
    container_name: headscale
    volumes:
      - ./config:/etc/headscale
      - headscale-data:/var/lib/headscale
    ports:
      - "8080:8080"    # gRPC
      - "443:443"      # HTTPS
    command: serve
    restart: unless-stopped

volumes:
  headscale-data:

Headscale eliminates the metadata concern because the coordination server runs on your hardware. The tradeoff is that you manage another service, and NAT traversal requires you to run your own DERP relay servers (or use Tailscale’s public ones, which defeats part of the purpose).

Headscale is well-maintained and has a growing community, but it lags behind Tailscale’s feature set by 6-12 months. If a feature matters to you, check Headscale’s compatibility matrix before committing.

ZeroTier Self-Hosted Controller

ZeroTier’s controller can be self-hosted using the official zerotier-one daemon with controller mode enabled. This replaces the my.zerotier.com web console with a local API:

# Enable controller mode (it is built into the zerotier-one daemon)
# The controller API is available at http://localhost:9993

# Create a network
curl -X POST http://localhost:9993/controller/network/${ZEROTIER_NODE_ID}______ \
  -H "X-ZT1-AUTH: $(cat /var/lib/zerotier-one/authtoken.secret)" \
  -d '{"name": "my-network"}'

Self-hosting the ZeroTier controller is officially supported and well-documented. It gives you complete control over network membership and routing without depending on ZeroTier’s cloud infrastructure.

NAT Traversal and Connectivity

NAT traversal is the most practical difference between these three for many self-hosters.

ScenarioWireGuardTailscaleZeroTier
Public IP on both endsWorksWorksWorks
One side behind NATWorks (port forward)Works (auto)Works (auto)
Both behind NATFails (needs relay)Works (DERP relay)Works (root relay)
CGNAT (carrier-grade NAT)FailsWorksWorks
Symmetric NATFailsWorks (via relay)Works (via relay)
Corporate firewall (only 80/443)Fails (uses UDP 51820)Works (DERP over HTTPS)Usually fails
Cellular networksUsually worksWorksWorks
Double NATFailsWorksWorks

This table is the single strongest argument for Tailscale over raw WireGuard. If you are on an ISP that uses CGNAT (increasingly common, especially with mobile providers and some fiber ISPs), WireGuard simply will not work without an intermediary VPS. Tailscale and ZeroTier handle this transparently.

Tailscale has an additional advantage: DERP relays operate over HTTPS on port 443, which means they work even on restrictive corporate networks that block non-standard ports. ZeroTier uses UDP on port 9993, which may be blocked by aggressive firewalls.

Mobile and Cross-Platform Support

PlatformWireGuardTailscaleZeroTier
LinuxKernel module (best)Userspace daemonUserspace daemon
macOSApp Store + CLIApp Store + CLIApp Store + CLI
WindowsOfficial GUI + CLIOfficial GUI + CLIOfficial GUI + CLI
iOSApp StoreApp StoreApp Store
AndroidPlay Store + F-DroidPlay StorePlay Store
ChromeOSVia Linux (Crostini)NativeVia Android app
OpenWrt/RoutersOfficial packageCommunity packageCommunity package
Synology NASCommunity packageOfficial packageCommunity package
QNAP NASCommunity packageCommunity packageCommunity package
tvOSNoYesNo
FreeBSDYes (userspace)YesYes

Tailscale has the broadest platform support, including native Apple TV support (useful for streaming through your tailnet). WireGuard has the deepest platform support thanks to being a protocol that anyone can implement.

Common Use Cases and Architectures

Use Case 1: Access Home Services from Anywhere

Best choice: Tailscale

Install Tailscale on your home server and your devices. Enable subnet routing if you need to reach devices without Tailscale installed. Access services by Tailscale IP or MagicDNS hostname. Five minutes to set up, zero ports exposed to the internet.

Use Case 2: Connect Two Sites (Home + Office or Home + VPS)

Best choice: WireGuard (site-to-site) or Tailscale (if NAT is involved)

For a dedicated site-to-site tunnel between two locations with static IPs, WireGuard is the simplest and fastest option. Configure one peer on each side, set AllowedIPs to the remote subnet, and you have a permanent, high-performance link.

If either site is behind NAT or CGNAT, use Tailscale with subnet routing on both ends.

Use Case 3: Share Services with Friends or Family

Best choice: Tailscale

Tailscale’s node sharing feature allows you to share specific devices with people outside your tailnet. They install Tailscale, you send them a sharing link, and they can access only the devices you have explicitly shared. This is significantly easier than managing WireGuard keys for non-technical users.

Use Case 4: IoT Network Isolation

Best choice: ZeroTier

ZeroTier’s Layer 2 networking and multiple network support makes it excellent for IoT segmentation. Create separate ZeroTier networks for different trust levels (trusted devices, IoT devices, guest devices) and use flow rules to control traffic between them.

Use Case 5: Gaming / Low-Latency Applications

Best choice: WireGuard

WireGuard’s kernel-level implementation adds less than 1ms of latency, making it suitable for gaming and real-time applications. Tailscale and ZeroTier’s userspace implementations add more latency, which can be noticeable in competitive gaming.

Use Case 6: Full Privacy (No Third-Party Trust)

Best choice: WireGuard or Headscale

If your threat model requires zero trust in third-party infrastructure, WireGuard with manual configuration or Tailscale clients with a self-hosted Headscale server are your options. Both keep all metadata and routing information on infrastructure you control.

Verdict: Which One Should You Use?

Choose WireGuard If:

  • You have a public IP address and can port forward
  • You enjoy understanding and controlling every aspect of your network
  • Maximum performance is important (e.g., large file transfers between sites)
  • You do not want to depend on any third-party service
  • You have a small, stable set of devices (not adding/removing frequently)
  • You are comfortable with Linux command-line administration
  • You want to run the VPN on a router (OpenWrt, pfSense)

Choose Tailscale If:

  • You want a VPN that works everywhere with zero networking expertise
  • You are behind CGNAT or complex NAT and cannot port forward
  • You need to share access with family or friends who are not technical
  • You value features like MagicDNS, Taildrop, and SSH integration
  • You want declarative ACLs that are easy to audit and version control
  • You are willing to trust Tailscale with your network metadata
  • You want something that works on every platform including Apple TV

Choose ZeroTier If:

  • You need Layer 2 networking (multicast, mDNS, non-IP protocols)
  • You want to self-host the entire control plane with official support
  • You need to bridge multiple physical LANs into a single virtual network
  • You have a specific use case that requires Ethernet-level networking
  • You need more than 3 users on a free plan (25 devices vs Tailscale’s 3-user limit)

The Honest Recommendation

For most self-hosters in 2026, Tailscale is the right choice. The setup is trivial, the NAT traversal is the best in the industry, MagicDNS eliminates the need to remember IP addresses, and the free tier is generous enough for most home labs. The metadata tradeoff is reasonable for the vast majority of threat models.

If the metadata concern bothers you, run Headscale as a self-hosted control plane and get the best of both worlds: Tailscale’s client experience with your own coordination server.

If you are a networking enthusiast who enjoys the control and performance of managing your own tunnels, WireGuard is a beautiful piece of engineering that will never let you down — as long as you can port forward.

ZeroTier is excellent for specific use cases (Layer 2 networking, multi-site bridging, self-hosted controllers) but has fallen behind Tailscale in general usability and community momentum. Unless you specifically need something ZeroTier offers that the others do not, start with Tailscale.

Final Thoughts

The VPN landscape for self-hosters is in a genuinely good place in 2026. WireGuard solved the protocol problem. Tailscale solved the usability problem. ZeroTier solved the virtual networking problem. All three are actively maintained, well-documented, and have generous free tiers.

The most important thing is to use something. Running self-hosted services exposed directly to the internet with only a password between your data and a botnet is not a risk worth taking. Any of these three solutions puts a cryptographic barrier between your services and the outside world, and that barrier is the single most impactful security improvement you can make to a home lab.

Install one today. It takes less time than reading this article did.