Tailscale vs Headscale: which control plane should you trust?
A blunt comparison of Tailscale and Headscale for self-hosted private networks, including Tailnet Lock, OIDC limits, exit nodes, and control-plane tradeoffs.
The real choice is not "open source versus closed source."
It is which control plane you are willing to trust, and how much operational work you are willing to do in order to move that trust boundary.
That is the question most comparison posts dodge. They talk as if the whole decision is ideological: hosted good, self-hosted pure; or hosted easy, self-hosted nerdy. Neither is useful.
Tailscale and Headscale both sit on top of WireGuard. The important difference is not the tunnel protocol. The important difference is who runs coordination, identity, node registration, route approval, and the higher-level plumbing that makes WireGuard feel effortless instead of manual.
What is actually open, and what is not
Tailscale's own open source page is refreshingly explicit:
- the client daemon is open source
- the DERP relay server is open source
- the coordination server is closed source
That same page explicitly points people who want a self-hosted coordination plane toward Headscale.
So the honest baseline is:
- Tailscale is not "mystery black box everywhere"
- Headscale is not "Tailscale, but every feature magically self-hosted"
Both of those caricatures waste time.
The fast decision table
| Question | Tailscale | Headscale |
|---|---|---|
| Coordination plane | Hosted SaaS | Self-hosted |
| Client compatibility | Excellent | Good, but you own the coordination side |
| Identity / org polish | Strong and low-friction | You own the OIDC and user lifecycle details |
| Trust reduction option | Tailnet Lock | Self-hosting the control plane outright |
| Exit nodes / routes | Polished | Supported, with more operator steps |
| Failure handling | SaaS-grade expectations | You own availability and rough edges |
| Best fit | Most people and most teams | Operators who truly require local control plane ownership |
That table is the answer in miniature. Everything below is why.
What Tailscale buys you besides WireGuard
People often describe Tailscale as "just WireGuard with nicer UX." That undersells what you are actually buying.
What you get is:
- node coordination
- identity integration
- stable client workflows
- sharing and org-level features
- routing and exit-node ergonomics
- a control plane that usually feels invisible until you need it
That invisible part is valuable. It means you are not spending your weekend re-learning how node registration, route approval, and auth lifecycle interact.
It also means you inherit product polish around everyday administrative chores that are easy to underestimate until you have to rebuild them. Tailscale's docs around things like multiple tailnets are a quiet reminder that "coordination plane" includes all the boring organizational edges too: how users belong to more than one network, how identity boundaries stay sane, and how you avoid turning every connectivity change into a bespoke admin ritual.
It is also why the best argument for Headscale is not "SaaS is bad." The best argument is "the fact of self-hosting the coordination plane is itself a requirement."
If that sentence does not already feel true in your environment, Tailscale starts with a large advantage.
Tailnet Lock is the real trust-model wrinkle
The most interesting Tailscale feature in this comparison is Tailnet Lock.
Tailnet Lock exists because Tailscale understands the obvious objection to a hosted coordination server: if the control plane can admit new nodes, then the control plane is powerful. Tailnet Lock changes that by requiring trusted nodes to sign admission of new nodes. In practice, it reduces how much blind trust you need to place in the coordination plane.
That does not eliminate operational burden. Tailnet Lock requires you to store disablement secrets safely and treat admission authority seriously.
That is the point.
It gives you a middle ground:
- keep the polished hosted coordination system
- move node-admission trust closer to your own devices
This matters because Headscale and Tailnet Lock solve different trust problems. Tailnet Lock says, "I will keep the hosted control plane, but I want stronger guarantees around who joins." Headscale says, "I want the coordination plane itself to be mine."
Do not flatten those into the same sentence.
What Headscale actually gives you
Headscale gives you a self-hosted coordination server for Tailscale clients. That is already enough value for some operators.
What it does not give you is automatic access to every polished Tailscale workflow or the hosted service's operational maturity. It is not a magical privacy upgrade by itself either.
The privacy improvement people really mean is usually one of these:
- control-plane metadata stays on infrastructure I run
- node registration and identity live inside my environment
- I do not want a third-party SaaS coordination service in the trust graph
Those are valid reasons.
What is not a valid reason is "self-hosted coordination must automatically be more secure because the word self-hosted sounds morally superior." You can self-host something badly. In fact, many people do.
Routes and exit nodes are where the operator tax appears
Headscale's routes documentation is a good place to see the practical tradeoff.
Yes, it supports:
- subnet routers
- exit nodes
- route approval
- ACL-based
autoApprovers
That is the good news.
The real news is the amount of state you now own:
- IP forwarding must be correct
- nodes must advertise routes or exit capability properly
- the control plane must approve those routes
- ACL policy must match what you think the network should do
A typical route advertisement flow looks like:
sudo tailscale up \
--login-server https://headscale.example.com \
--advertise-routes=10.0.0.0/24,192.168.50.0/24
headscale nodes list-routes
headscale nodes approve-routes --identifier 1 --routes 10.0.0.0/24,192.168.50.0/24
Exit node advertisement is similarly explicit:
sudo tailscale up \
--login-server https://headscale.example.com \
--advertise-exit-node
This is all perfectly workable. It is also not zero-friction.
The route docs also warn that failover can lag and in some situations may take up to 16 minutes to detect a node as offline. That is a real operational difference from "hosted SaaS mesh feels instant enough that I forgot it had a control plane at all."
If you are building around exit nodes, subnet routers, and failover expectations, this matters.
Identity is where the rough edges get real
The Headscale OIDC docs are probably the most important thing serious adopters should read before they start congratulating themselves about self-hosting.
The big practical limitation is simple: Headscale supports a single OIDC provider in configuration.
For a solo setup, that may be perfectly fine.
For a team or evolving environment, it means identity decisions are more constrained than the average "just self-host it" blog admits.
There is also a more subtle migration issue: Headscale stores a provider_identifier derived from the provider's issuer and subject claims. If you change OIDC providers, existing users may require manual cleanup or identifier updates.
That is not a theoretical edge case. It is the kind of thing that becomes your problem at exactly the moment the hosted alternative looks wonderfully boring.
This is why I say the self-hosted tax is not just "run the binary." It is:
- identity lifecycle
- route lifecycle
- approval workflow
- failure handling
- upgrades
- documentation drift
Those are the things you are actually taking ownership of.
Three honest recommendations
Use this decision box:
Choose Tailscale when:
- you want low-friction clients, sharing, and polished identity
- Tailnet Lock is enough control-plane assurance
Choose Headscale when:
- self-hosting the coordination plane is a hard requirement
- you accept OIDC, routing, and failover operational work
Then make it more specific.
Solo homelab
Use Tailscale unless the point of the project is explicitly "the coordination plane must run here." For a solo homelab, the hosted service plus Tailnet Lock usually buys back more time than self-hosting returns in principle.
Small team
Default to Tailscale even more strongly. Team identity, join workflow, sharing, and low-support clients are where hosted control planes justify themselves. The self-hosted coordination story gets harder the moment it stops being just you.
This is also where polished org behavior matters more than people admit. A solo operator can tolerate a slightly awkward join or identity workflow because the same person feels all the pain and can fix it. Teams multiply that cost. The comparison stops being "can I run the control plane?" and becomes "do I want every network-access change to also be an identity-operations project?"
"Control plane must be ours" operators
This is the real Headscale audience. If the requirement is non-negotiable, then Headscale is the honest answer. Just stop pretending the trade is free. You are buying back a trust boundary by accepting an availability, identity, and maintenance burden.
The RouteHarden opinion
Choose Tailscale unless the fact of self-hosting the coordination plane is itself a requirement.
That is the blunt answer.
Tailscale is better for most people because the coordination plane, identity plane, and client ergonomics are the whole product, not an embarrassing add-on around WireGuard. Tailnet Lock meaningfully improves the trust model without forcing you to become your own mesh-network vendor.
Choose Headscale when self-hosting the control plane is a real requirement, not a hobby reflex. It is a good tool for that job. It just does not erase the cost of doing that job.
If you want a mesh and what you really mean is "simple private connectivity between my devices," Tailscale is usually the right answer. If you want the control plane on infrastructure you own because that trust boundary matters enough to accept operational drag, Headscale is the right answer.
Both are legitimate choices.
The mistake is pretending they are the same choice with different vibes.