Tailscale vs Netbird: Self-Hosted Mesh VPNs Compared

Two WireGuard meshes, one of which you can actually own end to end

I have lost count of the number of times I have recommended Tailscale to people. It is, genuinely, the easiest way to get a flat, encrypted network across machines that have no business being on the same subnet — your laptop in a café, a VPS in Frankfurt, the NAS in the cupboard under the stairs. You install it, you log in, and suddenly everything can ping everything else over WireGuard with no port forwarding and no faff. It feels like magic.

But there is a catch I have learned to be honest about: the coordination server — the bit that hands out keys and tells nodes where to find each other — is Tailscale’s, not yours. The data plane is peer-to-peer WireGuard, so your traffic isn’t flowing through their servers. The control plane, however, is a SaaS you don’t run. For most people that’s fine. For some of us it itches. This is where Netbird, and Tailscale’s own open-source control server Headscale, come in.

Advertisement

Both Tailscale and Netbird build a WireGuard mesh. The honest difference is governance.

Tailscale’s client is open source; its coordination server is not. You can swap in Headscale, a community reimplementation of that control server, and self-host the whole thing — but Headscale is a separate project, not blessed by Tailscale, and you’re slightly off the beaten path.

Netbird, by contrast, is open source top to bottom — client, management server, signal server, and a built-in identity layer — and is explicitly designed to be self-hosted. It also uses WireGuard for the data plane, adds NAT traversal via its signal server, and ships a tidy web dashboard.

So the real comparison is: polished SaaS with optional unofficial self-hosting (Tailscale + Headscale) versus self-hosting as a first-class, supported path (Netbird).

Netbird’s quick-start is a single Docker Compose stack. After cloning their infra repo and running their setup script you’ll have something resembling this:

services:
  management:
    image: netbirdio/management:latest
    restart: unless-stopped
    volumes:
      - ./management.json:/etc/netbird/management.json
      - netbird-mgmt:/var/lib/netbird
    command:
      - "--port=80"
      - "--log-file=console"
      - "--disable-anonymous-metrics=true"
  signal:
    image: netbirdio/signal:latest
    restart: unless-stopped
  dashboard:
    image: netbirdio/dashboard:latest
    restart: unless-stopped
    environment:
      - NETBIRD_MGMT_API_ENDPOINT=https://netbird.example.com

volumes:
  netbird-mgmt:

You point an identity provider at it (Netbird bundles Keycloak in the full deploy, or you can wire up your own OIDC), and then on each machine:

$ curl -fsSL https://pkgs.netbird.io/install.sh | sh
$ netbird up --management-url https://netbird.example.com
Please do the SSO login in your browser.
Connecting to NetBird... Connected.
$ netbird status
Peers: 4/4 connected
NetBird IP: 100.92.0.3/16

Compare that to a Tailscale node, which is almost identical in feel:

$ tailscale up --login-server https://headscale.example.com
$ tailscale status
100.64.0.1   nas          smarc        linux   -
100.64.0.2   laptop       smarc        linux   active; direct

The --login-server flag is the whole trick for pointing Tailscale at Headscale instead of Tailscale’s own servers.

Netbird’s web dashboard is its real selling point. Access control via “groups” and policies is genuinely pleasant — you define groups, write rules like “the dev group may reach the databases group on port 5432”, and it just works. Headscale, by contrast, has historically been an ACL-file-and-CLI affair; capable, but you live in config.yaml and JSON policy files.

Tailscale’s edge is maturity and the surrounding features: MagicDNS, exit nodes, subnet routers, Taildrop, and an app-store-grade client on every platform including iOS and Android. Headscale supports a good chunk of this but lags the upstream, and you will occasionally find a feature that the official client expects the official server to provide.

NAT traversal is roughly a wash — both lean on WireGuard plus a relay (DERP for Tailscale, the signal server plus TURN for Netbird) when a direct connection can’t be punched. In practice you’ll see most peers connect directly after a few seconds of negotiation, with the relay catching only the awkward double-NAT cases. Worth noting too: with Netbird you’re running and updating the signal and management servers yourself, which is one more thing to monitor, whereas the official Tailscale path has none of that operational burden.

If you want the least friction and you can live with a third-party control plane, use Tailscale proper. It is the best in class and I still run it for my own laptops.

If self-hosting the control plane is a hard requirement, the choice is between Headscale (if you’re already deep in the Tailscale ecosystem and want its client features) and Netbird (if you want one coherent, fully open project with a dashboard and policy engine that were designed to be self-hosted from day one). For a fresh deployment where I’m doing it all myself, Netbird is the one I reach for — it’s less clever plumbing and more product. Just budget an evening for the identity-provider setup, because that’s the part everyone underestimates.

Advertisement

Related Content

Advertisement
Smarc
Written by Smarc

Founder and editor of vo.rs. A lifelong tinkerer who self-hosts far more than is sensible, hardens Linux boxes for fun, and prods the latest AI tools to see what they can really do. The how-to guides here are the notes Smarc wishes had existed the first time round.