DEV Community

Royce
Royce

Posted on • Originally published at ossalt.com

WireGuard vs OpenVPN: Self-Hosted VPN Comparison 2026

TL;DR

WireGuard is the right choice for most new self-hosted VPN deployments in 2026. It's faster (10Gbps+ throughput, ~1ms latency overhead), simpler (public/private key pairs, no certificate authority), and more secure (4,000 lines of code vs OpenVPN's 100,000+). OpenVPN wins in specific scenarios: corporate environments requiring TCP (firewall bypass on port 443), and situations requiring maximum compatibility with legacy systems. For a home lab, remote access VPN, or site-to-site tunnel: use WireGuard.

Key Takeaways

  • WireGuard: Built into the Linux kernel (since 5.6), ~10x faster than OpenVPN, 4K lines of code, UDP only
  • OpenVPN: Mature (since 2001), TCP support for firewall bypass, 100K+ lines, certificate-based auth
  • Setup complexity: WireGuard = key pairs only; OpenVPN = needs a certificate authority
  • wg-easy: Recommended web UI for WireGuard — deploys in minutes with Docker
  • Speed: WireGuard reaches 1–10 Gbps; OpenVPN peaks at ~200 Mbps under most setups
  • Use WireGuard for: personal VPN, home network access, site-to-site tunnels
  • Use OpenVPN for: TCP required, legacy system compatibility, corporate firewall bypass

Why Self-Host a VPN?

  • Privacy: No third-party VPN provider logs your traffic
  • Cost: A $6/month VPS runs a WireGuard server for unlimited users
  • Access to home/office network: Access LAN resources remotely
  • Split tunneling: Route only specific traffic through the VPN
  • Ad blocking: Combine with Pi-hole or NextDNS via the VPN

Comparison Overview

Feature WireGuard OpenVPN
License MIT GPL 2.0
Protocol UDP only UDP or TCP
Throughput 1–10+ Gbps ~100–200 Mbps
Latency overhead ~1ms ~5–10ms
Code size ~4,000 lines ~100,000+ lines
Attack surface Minimal Larger
Auth method Public/private key pairs Certificates (CA required)
Config complexity Simple Complex
Kernel integration Built into Linux 5.6+ Userspace TUN/TAP
Firewall bypass UDP (port 51820) TCP port 443 option
Mobile clients iOS, Android iOS, Android
Windows/macOS Official apps Official apps
Stealth mode Yes (ignores unknown packets) No
GitHub Stars ~14K (wireguard-tools) ~9K

WireGuard: The Modern Choice

WireGuard was merged into the Linux kernel in version 5.6 (March 2020) — this alone signals its quality. Linus Torvalds called it "a work of art." The entire codebase is ~4,000 lines, compared to OpenVPN's 100,000+. Less code means a smaller attack surface and easier security auditing.

Why WireGuard is Better for Most Use Cases

Speed. WireGuard uses ChaCha20 for symmetric encryption and Poly1305 for message authentication — modern, efficient cryptography. Real-world throughput commonly reaches 1–10 Gbps, while OpenVPN typically plateaus around 100–200 Mbps due to TLS overhead and userspace processing.

Simplicity. Authentication is pure public/private key cryptography — similar to SSH keys. No certificate authority, no certificate revocation lists, no certificate expiry to manage.

Stealth. WireGuard doesn't respond to packets from unknown sources — a port scan won't even show the port as open. The server appears as if it's not there unless you authenticate.

Built into Linux. WireGuard is a kernel module on any Linux system running 5.6+ (Ubuntu 20.04+). No packages to install on the server — just apt install wireguard-tools.

Quick WireGuard Setup

# Install on Ubuntu 22.04+ (kernel module already included):
sudo apt install wireguard wireguard-tools

# Generate server keys:
wg genkey | tee server_private.key | wg pubkey > server_public.key

# /etc/wireguard/wg0.conf (server):
[Interface]
PrivateKey = <server-private-key>
Address = 10.0.0.1/24
ListenPort = 51820
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
# Client 1:
PublicKey = <client1-public-key>
AllowedIPs = 10.0.0.2/32
Enter fullscreen mode Exit fullscreen mode
# Enable IP forwarding:
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p

# Start WireGuard:
wg-quick up wg0
systemctl enable wg-quick@wg0
Enter fullscreen mode Exit fullscreen mode

wg-easy: Web UI for WireGuard (Recommended)

Managing WireGuard config files manually is error-prone. wg-easy provides a simple web UI for managing peers — ~25K GitHub stars.

# docker-compose.yml for wg-easy:
services:
  wg-easy:
    image: ghcr.io/wg-easy/wg-easy:latest
    container_name: wg-easy
    environment:
      WG_HOST: your-server-ip-or-domain    # Public IP or hostname
      PASSWORD_HASH: $2b$12$your-hash-here  # bcrypt hash of admin password
      WG_DEFAULT_DNS: 1.1.1.1
      WG_DEFAULT_ADDRESS: 10.8.0.x
      WG_PORT: 51820
      WG_ALLOWED_IPS: 0.0.0.0/0            # Route all traffic through VPN
      # WG_ALLOWED_IPS: 10.8.0.0/24        # Split tunnel: only VPN subnet
    volumes:
      - wg-easy_data:/etc/wireguard
    ports:
      - "51820:51820/udp"
      - "51821:51821/tcp"    # Web UI
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1
      - net.ipv4.ip_forward=1
    restart: unless-stopped

volumes:
  wg-easy_data:
Enter fullscreen mode Exit fullscreen mode

Generate the bcrypt password hash:

docker run ghcr.io/wg-easy/wg-easy wgpw 'your-password'
# Outputs: $2b$12$...
Enter fullscreen mode Exit fullscreen mode

Access the web UI at http://your-server:51821. Create a new client, download the config or QR code, and connect.

WireGuard Clients

Platform Client
iOS WireGuard (official App Store)
Android WireGuard (official Play Store)
macOS WireGuard (official App Store or Homebrew)
Windows WireGuard (wireguard.com/install)
Linux wg-quick (built-in)

OpenVPN: Battle-Tested for 20+ Years

OpenVPN has been the standard self-hosted VPN since 2001. While WireGuard outperforms it technically, OpenVPN excels in specific scenarios.

When OpenVPN is the Right Choice

TCP mode for firewall bypass. OpenVPN can run on TCP port 443, making it look like HTTPS traffic. If you're in an environment that blocks UDP or restricts VPN ports (corporate networks, hotels, public WiFi), OpenVPN on port 443 goes through almost universally.

Maximum compatibility. OpenVPN works on platforms that may not yet support WireGuard well: older Android versions, some network equipment, certain enterprise MDM systems.

Established ecosystem. OpenVPN has deep integration with commercial routers (DD-WRT, pfSense, OPNsense), firewall appliances, and enterprise MDM solutions.

Quick OpenVPN Setup with Docker

The easiest self-hosted OpenVPN setup uses kylemanna/openvpn:

# Initialize OpenVPN config:
docker run -v openvpn_data:/etc/openvpn --rm kylemanna/openvpn ovpn_genconfig \
  -u udp://YOUR_SERVER_IP

docker run -v openvpn_data:/etc/openvpn --rm -it kylemanna/openvpn ovpn_initpki
Enter fullscreen mode Exit fullscreen mode
# docker-compose.yml:
services:
  openvpn:
    image: kylemanna/openvpn:latest
    cap_add:
      - NET_ADMIN
    volumes:
      - openvpn_data:/etc/openvpn
    ports:
      - "1194:1194/udp"
    restart: unless-stopped

volumes:
  openvpn_data:
Enter fullscreen mode Exit fullscreen mode
# Generate a client certificate:
docker run -v openvpn_data:/etc/openvpn --rm -it kylemanna/openvpn easyrsa build-client-full client1 nopass

# Export the client .ovpn config file:
docker run -v openvpn_data:/etc/openvpn --rm kylemanna/openvpn ovpn_getclient client1 > client1.ovpn
Enter fullscreen mode Exit fullscreen mode

TCP Mode (Firewall Bypass)

# Initialize with TCP on port 443:
docker run -v openvpn_data:/etc/openvpn --rm kylemanna/openvpn ovpn_genconfig \
  -u tcp://YOUR_SERVER_IP:443 -e 'port 443' -e 'proto tcp'
Enter fullscreen mode Exit fullscreen mode

Performance Comparison

Real-world throughput on a VPS (1 vCPU, 1GB RAM):

Protocol Throughput Latency Overhead CPU Load
WireGuard (UDP) 1–10 Gbps ~1ms Low
OpenVPN (UDP) 100–200 Mbps ~5–10ms Medium-High
OpenVPN (TCP) 50–100 Mbps ~10–20ms High

WireGuard's performance advantage comes from:

  • Kernel-space implementation (vs OpenVPN's userspace TUN/TAP)
  • Modern cryptography (ChaCha20 + Poly1305 vs OpenSSL's AES)
  • Minimal protocol overhead

Use Case Decision Guide

Use WireGuard if:
  → Home lab or personal VPN
  → Remote access to your home/office network
  → Site-to-site tunnels between VPS instances
  → You want speed and simplicity
  → Your clients run modern OS (Linux 5.6+, iOS 14+, Android 5+, Windows 10+)
  → Self-hosting from scratch (no legacy requirements)

Use OpenVPN if:
  → Strict firewall environments (TCP port 443 needed)
  → Corporate environments with UDP blocked
  → Legacy device compatibility required
  → You need deep router/firewall appliance integration
  → Your pfSense/OPNsense setup uses OpenVPN already

Consider Tailscale if:
  → You don't want to manage a VPN server at all
  → You need mesh networking (each device connects to each other)
  → The free tier (100 devices) is sufficient
  → Headscale (self-hosted Tailscale coordination server) for full self-hosting
Enter fullscreen mode Exit fullscreen mode

Alternatives Worth Knowing

Tool Protocol License Stars Notes
wg-easy WireGuard MIT ~25K Best WireGuard web UI
Firezone WireGuard Apache 2.0 ~7K Enterprise features, SSO
Headscale WireGuard (Tailscale-compatible) BSD ~20K Self-hosted Tailscale
Outline ShadowSocks Apache 2.0 ~40K Censorship circumvention
SoftEther Multi-protocol Apache 2.0 ~11K Windows VPN compat.

Methodology

  • Performance data: community benchmarks from WireGuard forum, ServeTheHome, Reddit r/selfhosted (2025–2026)
  • GitHub stars: Verified March 2026
  • Protocol specs: wireguard.com, OpenVPN documentation
  • Kernel integration: Linux 5.6 release notes (March 29, 2020)

Compare all open source networking and security tools at OSSAlt.com/categories/networking.

Top comments (0)