WireGuard benchmark on Linux, Oct 2026
Quantum against wireguard-go, kernel WireGuard, boringtun and OpenVPN on Linux lab VMs in October 2026: throughput, CPU, memory, latency and the losses.
Key takeaways
- 10717 Mbit/s for Quantum against 4016 for wireguard-go on one TCP stream, with one vCPU and one thread per side, on a Linux lab VM on 2026-10-30.
- Quantum at 2 and 4 threads carried 8822 and 10030 Mbit/s on one TCP stream between two VMs on one host, against wireguard-go's 4929 and 7438 (2026-10-30).
- wireguard-go spent 1.7 to 2.6 times Quantum's CPU per gigabit in 12 measurements; our 2.5-times target was met in 2 of them and in no single-stream one.
- Quantum's process peaked at 5.5-6.8 MB between VMs, against 116-434 MB for wireguard-go in the same single-stream window.
- 4.72 ms ping p99 under load for Quantum against 2.27 for kernel WireGuard between two 2-vCPU VMs (2026-10-30): latency is where Quantum lost.
On this page (11)
- How was this WireGuard benchmark run?
- Which tunnel carried the most traffic?
- How much CPU does each gigabit cost?
- How much memory does each tunnel use?
- What happens to latency under load?
- How does Quantum compare with OpenVPN?
- What changed since our earlier Linux runs?
- Where did Quantum lose or tie?
- What does this benchmark not show?
- Which tunnel should you pick on a Linux server?
- What changed on this page
On 2026-10-30, on x86_64 Linux virtual machines in our lab, Quantum, ForestVPN's tunnel engine, carried more single-stream TCP traffic than wireguard-go wherever the network link was not the limit: 1.33 to 2.67 times as much with each side held to 1, 2 or 4 vCPUs, and 1.35 to 1.79 times between two VMs on one host, with Quantum set to as many threads as vCPUs (its default is one) (home-lab run). Over a 2.5 Gbit/s link, Quantum, wireguard-go and kernel WireGuard all reached about 95 percent of the link: a tie (home-lab run). For each gigabit carried, wireguard-go spent 1.7 to 2.6 times Quantum's CPU above the no-tunnel baseline, with Quantum in whichever setting cost it less (mostly one thread, because more threads cost more CPU per gigabit); our target was 2.5 times, met in 2 of 12 measurements and in no single-stream one. Quantum lost on latency under load to kernel WireGuard and boringtun. Nothing here describes phones, Macs, Windows PCs or routers.
How was this WireGuard benchmark run?
Three setups in our lab, every comparison inside one run with its own no-tunnel control, five runs per cell in shuffled order, the minimum and maximum kept next to every median.
How this was tested
- Product
- Quantum (fv run, source of 2026-10-30), wireguard-go v0.0.20250522, boringtun 0.7.0, kernel WireGuard; OpenVPN 2.7.0 with DCO in a separate run
- Version
- iperf3 3.20
- System
- Ubuntu 26.04.1, kernel 7.0.0-38, x86_64 VMs on AMD Ryzen 7 8845HS hosts
- Checked
- Runs
- 5
Not tested
Measured 2026-10-30 in our lab: x86_64 virtual machines on AMD Ryzen 7 8845HS hosts (Proxmox), Ubuntu 26.04.1, kernel 7.0.0-38, iperf3 3.20, one and four TCP streams for 15 s, median of 5 runs in shuffled order, every comparison inside one run with its own no-tunnel control. Quantum is the fv run Linux daemon built from our source on 2026-10-30 (commit 1b2e632533; a glibc build, not the packaged binary; as of 2026-10-30 no published release contains these changes), at one thread (its default) and with --threads N, the optional extra key exchange off. wireguard-go v0.0.20250522 runs with as many Go threads as vCPUs, boringtun 0.7.0 (Cloudflare's userspace WireGuard in Rust) with --threads equal to the vCPU count, and kernel WireGuard as a reference. Three setups: one VM with two network namespaces, each side held to 1, 2 or 4 vCPUs; two VMs of 2 or 4 vCPUs on one host, where CPU cycles were counted host-wide (iperf3 and the kernel network stack included); two 4-vCPU VMs on two hosts over a 2.5 GbE link. Other projects' VMs shared the lab hosts. The raw runs and harness are in our private repository. No phone, tablet, Mac, Windows PC or router was measured.
CPU per gigabit is the busy CPU time of both VMs per gigabit delivered, minus the same figure with no tunnel. "wireguard-go spent 2 times Quantum's" means wireguard-go's figure divided by Quantum's. Our target was 2.5 times, scored in one setting per measurement: Quantum at one thread or at as many threads as vCPUs, whichever used less CPU while carrying at least wireguard-go's traffic.
The OpenVPN figures come from a separate run: OpenVPN 2.7.0 over UDP with AES-256-GCM, in userspace and with the Linux 7.0 kernel's own DCO driver, beside Quantum (--threads equal to the vCPU count), wireguard-go and kernel WireGuard; one TCP stream for 15 s, median of 5 runs. OpenVPN moves one stream through one process or one kernel path, so it got no extra threads: this is each tunnel as it runs, not a matched-cores test. Figures from this run are never compared with the main run's, and say nothing about OpenVPN 2.6.
Quantum speaks WireGuard's unmodified Noise_IKpsk2 handshake (the Noise protocol pattern WireGuard uses, with a pre-shared key); the protocol page has the details. We measured throughput with iperf3.
Which tunnel carried the most traffic?
Where the CPU was the limit, Quantum with as many threads as vCPUs carried more than wireguard-go at every core count we ran (home-lab run). At one thread on 4 vCPUs it carried less.
| vCPUs per side | Quantum, 1 thread | Quantum, threads = vCPUs | wireguard-go |
|---|---|---|---|
| 1 | 10717 (10645-10807) | same as 1 thread | 4016 (3731-4139) |
| 2 | 10529 (10436-10585) | 12308 (11648-12469) | 7358 (7193-7438) |
| 4 | 10525 (10437-10620) | 14911 (11693-15230) | 11194 (10816-11354) |
Show the data
| Quantum, 1 thread | 10717 Mbit/s |
|---|---|
| wireguard-go | 4016 Mbit/s |
| boringtun, 1 thread | 3422 Mbit/s |
With threads set to the vCPU count, Quantum carried 2.67, 1.67 and 1.33 times wireguard-go's traffic at 1, 2 and 4 vCPUs, and the ranges do not overlap (home-lab run). At one thread it carried 1.43 times at 2 vCPUs and 0.94 times at 4: less. Kernel WireGuard is left out of this table, because its encryption runs in kernel threads we cannot hold to the same vCPUs, so it is not a matched comparison. With one vCPU and one thread each, boringtun (Cloudflare's userspace WireGuard in Rust) carried 3422 Mbit/s; its other figures in this lab are unexplained (see below), so that is the only boringtun result we use (home-lab run).
| vCPUs per VM | Quantum, 1 thread | Quantum, threads = vCPUs | wireguard-go | Kernel WireGuard |
|---|---|---|---|---|
| 2 | 7638 (7503-7739) | 8822 (8623-9084) | 4929 (4599-5095) | 5402 (4917-5588) |
| 4 | 7553 (7521-7593) | 10030 (8934-10182) | 7438 (7415-7607) | 4513 (4358-4533) |
Show the data
| Quantum, 4 threads | 10030 Mbit/s |
|---|---|
| Quantum, 1 thread | 7553 Mbit/s |
| wireguard-go | 7438 Mbit/s |
| Kernel WireGuard | 4513 Mbit/s |
Between two VMs on one host, Quantum with threads set to the vCPU count carried 1.79 times wireguard-go's traffic at 2 vCPUs and 1.35 times at 4 (home-lab run). At one thread and 4 vCPUs the two tied: 7553 against 7438, with overlapping ranges. Kernel WireGuard carried less than Quantum at both sizes, and less at 4 vCPUs than at 2, in this run and in the OpenVPN run the same day; we have not found why, so read its 4-vCPU figure with care.
Over a 2.5 Gbit/s link between two hosts, the plain connection carried 2272 Mbit/s and Quantum 2164, wireguard-go 2170 and kernel WireGuard 2168 (home-lab run). That is a tie at the link, and we rank nothing there.
How much CPU does each gigabit cost?
Less for Quantum than for wireguard-go in every measurement, but by the 2.5 times we aimed for in only 2 of 12 (home-lab run).
| Setup | Quantum setting scored | One TCP stream | Four TCP streams |
|---|---|---|---|
| One VM, 1 vCPU per side | 1 thread | 1.75 | 2.12 |
| One VM, 2 vCPUs per side | 1 thread | 2.10 | 2.63 |
| One VM, 4 vCPUs per side | 4 threads | 2.04 | 2.38 |
| Two VMs over 2.5 GbE | 1 thread | 1.72 | 2.22 |
| Two VMs on one host, 2 vCPUs | 2 threads (one stream), 1 thread (four) | 1.97 | 2.37 |
| Two VMs on one host, 4 vCPUs | 1 thread | 2.02 | 2.57 |
Two of the twelve met the target, both with four streams: 2.63 (worst run 2.61) and 2.57 (worst run 2.44). On one stream the ratio stayed between 1.72 and 2.10 (home-lab run). More threads bought throughput at up to 22 percent more CPU per gigabit than one thread, so Quantum's highest throughput and its lowest CPU cost come from different settings.
Between two VMs on one host, where the processor's counters were visible, the whole host spent 13.1 CPU cycles per delivered byte with Quantum at one thread and 12.7 at 2 threads (2 vCPUs), and 13.8 and 15.0 at 1 and 4 threads (4 vCPUs), against 22.8 and 25.5 for wireguard-go (home-lab run). The count includes iperf3 and the kernel network stack, so it compares tunnels within this setup only.
How much memory does each tunnel use?
| Setup and window | Quantum | boringtun | wireguard-go |
|---|---|---|---|
| Two VMs over 2.5 GbE, single-stream window | 5.5 (1 thread), 6.5 (4 threads) | 7.4 | 116 |
| Two VMs on one host, 2 vCPUs, single-stream window | 5.6 (1 thread), 6.5 (2 threads) | 7.1 | 422 |
| Two VMs on one host, 4 vCPUs, single-stream window | 5.6 (1 thread), 6.8 (4 threads) | 7.4 | 434 |
| One VM, 1 to 4 vCPUs per side, whole run | 5.6 to 7.0 | 4.2 to 4.6 | 1070 to 1409 |
boringtun was the smaller of the two Rust tunnels on the one-VM setup, so we do not call Quantum the smallest (home-lab run). More threads cost Quantum 0.9 to 1.3 MB (home-lab run). wireguard-go's memory grows with the traffic it has carried, which is why the one-VM figures, read over a whole run, are higher. Kernel WireGuard runs no comparable process.
What happens to latency under load?
Quantum lost here. While one TCP stream ran between two VMs on one host, its ping p99 was 4.72 ms at one thread and 5.69 at 2 threads (2 vCPUs), and 4.74 and 4.03 at 1 and 4 threads (4 vCPUs) (home-lab run). Kernel WireGuard had 2.27 and 3.12 ms, boringtun 1.83 and 1.61, wireguard-go 10.0 and 6.28 (home-lab run). Over the 2.5 Gbit/s link Quantum, wireguard-go and kernel WireGuard all sat near 8 ms (home-lab run). Each tunnel was measured at its own throughput, and boringtun carried far less, but we report the result as a loss (home-lab run).
How does Quantum compare with OpenVPN?
In a separate run the same day, between two VMs on one host (OpenVPN run):
| Tunnel | 2 vCPUs | 4 vCPUs |
|---|---|---|
| Quantum (threads = vCPUs) | 9449 (9162-9679) | 10203 (9259-10485) |
| wireguard-go | 5034 (4976-5135) | 7535 (7418-7696) |
| Kernel WireGuard | 5544 (5031-5556) | 4618 (4379-4630) |
| OpenVPN 2.7.0 with DCO | 3754 (3173-3776) | 3622 (3475-3721) |
| OpenVPN 2.7.0, userspace | 588 (586-589) | 740 (577-753) |
Quantum carried 2.5 and 2.8 times what OpenVPN with DCO did and 16 and 14 times userspace OpenVPN, at 12.7 and 14.2 CPU cycles per byte against DCO's 22.6 and 23.6 (OpenVPN run). OpenVPN moves one stream through one process or one kernel path, so it had no extra threads to use: this is each tunnel as it runs, not matched cores. OpenVPN won on latency (OpenVPN run): ping p99 under that load was 1.43 and 1.85 ms with DCO and about 1.5 ms in userspace, against Quantum's 5.52 and 3.92. Over a 2.5 Gbit/s link (OpenVPN run), every tunnel but userspace OpenVPN reached the link, and DCO used the least host CPU per gigabit of any, 0.48 CPU seconds against Quantum's 0.67 (whole host, no-tunnel baseline not subtracted). OpenVPN used AES-256-GCM and the WireGuard family ChaCha20-Poly1305. These figures are about OpenVPN 2.7.0 and are not compared with the main run's.
What changed since our earlier Linux runs?
The code. In the same run, the build of Quantum before these changes carried 2.2 to 3.1 times less on one stream (4855 Mbit/s against 10717 at 1 vCPU) and had 35000 to 42000 TCP retransmissions per 15 s window where the new build had none (home-lab run). The new build spends 14 to 25 percent less CPU per gigabit at one thread in the one-VM and same-host setups. It also has a higher ping p99 under load (home-lab run), 3.3 ms against about 0.4 on one VM (the old build dropped packets where the new one queues them), spends 6.6 percent more CPU per gigabit on one stream over the 2.5 Gbit/s link, and holds 0.7 to 0.9 MB more memory at one thread.
What changed is how the Linux daemon receives (it now takes the batches the kernel coalesces), a fix for datagrams the old receive loop dropped after the kernel had handed them over, and, with --threads above 1 on Linux, encryption on helper threads. The handshake and the wire format did not change.
Our 2026-10-16 and 2026-10-17 runs on Scaleway servers measured the build before these changes, and there kernel WireGuard and wireguard-go carried about two to three times Quantum's traffic (earlier build). They stay on the compare page as the earlier build. They used other machines, kernels and builds, so we compare nothing across them, and they do not measure what the changes gained (home-lab run).
Where did Quantum lose or tie?
- Latency under load: higher than kernel WireGuard's, boringtun's and OpenVPN's, in every setup where they could be told apart.
- The 2.5 Gbit/s link: a tie with wireguard-go and kernel WireGuard (home-lab run).
- CPU target: 2.5 times wireguard-go's efficiency in 2 of 12 measurements, none on one stream.
- One thread on 4 vCPUs: 0.94 times wireguard-go's traffic on one VM, a tie between two VMs.
- Many peers: with 16 peers on one endpoint, Quantum at 4 threads shared the traffic less evenly than wireguard-go and dropped frames that wireguard-go did not. That run had a smaller VM than planned, so we publish no figure from it.
What does this benchmark not show?
- Other platforms: nothing here carries over to phones, tablets, Macs, Windows PCs, routers or the apps, and none of them was measured in these runs. The router figures come from a separate run on 2026-09-01.
- The packaged build: we ran a glibc build from source; the packages ship a static build, and on 2026-10-30 no published release contained these changes (home-lab run).
- A real WAN: every setup is virtual machines in one lab, and other projects' VMs shared the hosts.
- Kernel WireGuard as a matched rival: on one VM it could not be held to the same vCPUs, and between VMs it carried less at 4 vCPUs than at 2 for reasons we have not found.
- boringtun outside one vCPU: its figures fell with more threads and between VMs, which we have not explained.
- UDP, connect time and production settings: no UDP or connect-time figures, and the optional extra key exchange that production servers run was off.
- Across runs: we never divide a figure of one run by one from another.
Which tunnel should you pick on a Linux server?
Where the CPU is the limit, Quantum with --threads set to the core count carried more single-stream traffic than wireguard-go and boringtun in every setup we ran, and more than kernel WireGuard and OpenVPN between two VMs on one host. If latency under load matters more than throughput, kernel WireGuard and OpenVPN with DCO had the lower figures. If the link is the limit, as at 2.5 Gbit/s here, the WireGuard-family tunnels all reached it (home-lab run), and the choice comes down to everything else. Choose Quantum too if you want ForestVPN's engine on a Linux server.
What changed on this page
- 2026-10-30: rewritten around the 2026-10-30 home-lab run of the current build and a same-day OpenVPN run; the 2026-10-16 and 2026-10-17 Scaleway runs of the earlier build moved to the compare page.
Questions and answers
Is kernel WireGuard faster than wireguard-go?
It depended on the cores. Between two 2-vCPU VMs on one host on 2026-10-30, kernel WireGuard carried 5402 Mbit/s on one TCP stream and wireguard-go 4929, with overlapping ranges, so about the same. Between two 4-vCPU VMs, wireguard-go carried 7438 against 4513. Over a 2.5 Gbit/s link both reached the link. We have not found why the kernel module carried less at 4 vCPUs than at 2.
How much memory does a userspace WireGuard tunnel use?
In our 2026-10-30 Linux runs, Quantum's process peaked at 5.5 to 7.0 MB and boringtun's at 4.2 to 7.4 MB, so neither is clearly smaller. wireguard-go peaked at 116 to 434 MB in the single-stream window between two VMs, and at 959 to 1428 MB over a whole run on one VM. Kernel WireGuard runs no comparable process.
Did Quantum reach its CPU target?
Mostly not. The target was for wireguard-go to spend 2.5 times Quantum's CPU per gigabit above the no-tunnel baseline. Across 12 measurements on 2026-10-30 it spent 1.7 to 2.6 times; 2 of 12 met the target, both with four TCP streams, and no single-stream measurement did (1.72 to 2.10).
How does OpenVPN compare?
In a separate run on 2026-10-30 between two VMs on one host, OpenVPN 2.7.0 with kernel offload (DCO) carried 3754 and 3622 Mbit/s on one TCP stream at 2 and 4 vCPUs and userspace OpenVPN 588 and 740, against Quantum's 9449 and 10203 at 2 and 4 threads. OpenVPN moves one stream through one process, so this is each tunnel as it runs, not matched cores. OpenVPN had the lower latency under load.
Does the boringtun result describe boringtun as shipped?
Only one cell is comparable. With one vCPU and one thread each, Quantum carried 10717 Mbit/s against boringtun's 3422. boringtun carried less with more threads in that setup and 712 to 761 Mbit/s between two VMs, which we have not explained, so we make no other boringtun claim.
Do these numbers apply to the phone or desktop apps?
No. They measure the Linux daemon fv run, built from our source on 2026-10-30, on x86_64 virtual machines. No published release contained these changes on that date, and we make no claim about phones, tablets, Macs, Windows, routers or the apps from this run.
Sources
- WireGuard protocol and cryptography (read October 16, 2026)
- OpenVPN data channel offload (DCO) (read October 16, 2026)
- iperf3, the network throughput tool (read October 16, 2026)
How this was made
AI-assisted drafting from our own 2026-10-30 benchmark data, then automated checks and editorial review.