Tailscale is the right answer for about 90% of homelabs: NAT traversal that just works, identity-based access, and a five-minute setup with a free tier (3 users, 100 devices) that covers a household. Plain WireGuard wins when you have a public IP, want zero third parties in the control path, and don't mind managing keys. Cloudflare Tunnel is for the different problem of publishing a few web apps to people who will never install anything. All three are categorically safer than the thing they replace — port-forwarding service dashboards to the open internet.

The remote access decision in one table

WireGuardTailscaleCloudflare Tunnel
What it isKernel VPN protocolMesh built on WireGuardOutbound HTTPS tunnel to Cloudflare's edge
Open inbound portsOne UDP portNoneNone
Works behind CGNATNo (needs reachable endpoint)Yes (DERP relays as fallback)Yes
Third party in pathNoneCoordination server (or self-host Headscale)Cloudflare proxies and can read traffic
Non-web protocols (SSH, SMB)YesYesHTTP-first; TCP possible but clunky
PerformanceKernel speed, near line rateSame when direct; slower via relayFine for web apps; not for bulk transfer
Setup effortMedium (keys, configs, DDNS)TrivialLow (domain on Cloudflare required)
CostFreeFree tier; paid teamsFree

Tailscale: the default, and what you're trusting

Install the client, sign in with an existing identity provider, and every device sees every other device over encrypted WireGuard tunnels — Tailscale's coordination server only exchanges public keys and endpoints; traffic goes peer-to-peer, falling back to encrypted DERP relays for the ~10% of NAT situations that defeat hole-punching. The features that matter in practice: a subnet router advertises your whole LAN so un-installable devices (printers, the NAS) are reachable; an exit node turns any machine into your VPN egress for hostile hotel Wi-Fi; MagicDNS gives every device a stable name; ACLs restrict the kids' devices to Jellyfin and nothing else.

What you're trusting: a company's coordination plane for authentication and key distribution — it can't read your traffic, but it does know your device inventory and could, if compromised, add a node to your network. If that sits wrong, Headscale is the self-hosted, open-source implementation of the coordination server; official clients point at it with one flag, and the trade is that availability and upgrades become your job. Running Headscale on a $4 VPS is a popular middle path: sovereignty over the control plane without hosting it behind the very NAT you're trying to escape.

WireGuard: nothing between you and the kernel

Plain WireGuard is ~4,000 lines of audited kernel code, a config file of keys, and nothing else running anywhere. On homelab hardware it saturates gigabit with 1–2ms of added latency, and its silence is a security feature — an unauthenticated packet gets no response at all, so scanners see nothing listening. The requirements: UDP port 51820 forwarded, a stable address (DDNS if your ISP rotates IPs), and no CGNAT — if your ISP puts you behind carrier-grade NAT, skip straight to Tailscale. The wg-easy container gives you a web UI with QR-code enrolment for phones:

services:
  wg-easy:
    image: ghcr.io/wg-easy/wg-easy:latest
    environment:
      - WG_HOST=vpn.example.com
    ports:
      - "51820:51820/udp"
      - "127.0.0.1:51821:51821/tcp"   # admin UI — keep it off the internet
    cap_add: [NET_ADMIN, SYS_MODULE]
    volumes:
      - ./config:/etc/wireguard
    restart: unless-stopped

The operational cost is real but small: you are now the one rotating keys, revoking the lost phone, and debugging the friend's router that blocks UDP. For two or three devices and one technical operator, it's the cleanest possible design.

Cloudflare Tunnel: publishing, not remoting

Cloudflare Tunnel solves a different problem. The cloudflared daemon makes an outbound connection to Cloudflare's edge; visitors hit recipes.example.com through Cloudflare, which proxies down the tunnel. No open ports, origin IP hidden, DDoS absorbed, free. The catch is in the trust column: Cloudflare terminates TLS, so it can read the traffic — fine for a recipe app or wedding site, wrong for a password manager. Two more constraints: your domain's DNS must live on Cloudflare, and it's built for HTTP — streaming a media library through it is against the spirit and sometimes the letter of the free tier's terms. Pair public hostnames with Cloudflare Access policies (email one-time-codes for grandma) and you have authenticated public sharing with zero client software.

Combining them without over-engineering

The stable homelab pattern is one tool per audience. You and your household: Tailscale on every device, subnet router on the server. A handful of public web apps for outsiders: Cloudflare Tunnel with Access in front. WireGuard instead of Tailscale if you have the public IP and prefer auditable minimalism. Signs you've over-engineered: all three running for one user, or a VPN mesh and a tunnel both exposing the same service. Remote access is also the layer where mistakes are quiet — an exposed dashboard looks identical to a safe one until the log review — so keep the surface countable on one hand. More options live in the remote access category, and the Jellyfin guide shows the pattern applied to the classic "family wants the media server" case.

What I'd do

Start with Tailscale tonight — client on the server, subnet router enabled, apps on the phones; you'll be reading your dashboards from anywhere within the hour. Move the control plane to Headscale only if third-party coordination genuinely bothers you. Add a Cloudflare Tunnel the day someone outside the house needs a browser-only path to one specific app. And keep plain WireGuard in your pocket for the site-to-site link between your house and the off-site backup box — the job it does with nothing else in the blast radius.