COLITU LABProbes starting

Can It Survive? #1 · Controlled experiment

How VPN protocols cope with packet loss

Four VPN protocols between two servers while the network drops 0, 1, 5 and 10 % of packets in both directions. Download speed and page-load times, three runs each.

In short. At 1 % loss in each direction, WireGuard kept 48 % and OpenVPN 28 % of their own clean-network download speed, while VLESS Reality (97 %) and Hysteria2 (96 %) kept about as much as the connection without a VPN (97 %). At 10 % loss VLESS Reality still matched no VPN (78 % vs 77 %), Hysteria2 kept 47 %, and the two IP tunnels 4 %. This is one route under one set of conditions; read the limits before quoting it.

Download speed kept under packet loss

Median of 3 runs, as a share of each protocol's own speed at 0 % loss. Hover or use the arrow keys for the values.

Raw data
0%25%50%75%100%0 %1 %5 %10 %Packet loss, each direction
Data table
Speed kept0 % loss1 % loss5 % loss10 % loss
No VPN100%97%88%77%
Hysteria2100%96%91%47%
VLESS Reality100%97%90%78%
WireGuard100%48%15%4%
OpenVPN (UDP)100%28%12%4%

Download speed

Mbit/s, median of 3 runs; in brackets the share of the protocol's own 0 % speed.

Loss, each wayNo VPNHysteria2VLESS RealityWireGuardOpenVPN (UDP)
0 %86.480.685.175.775.3
1 %83.8 (97 %)77.7 (96 %)82.9 (97 %)36.3 (48 %)20.8 (28 %)
5 %75.8 (88 %)73.6 (91 %)76.4 (90 %)11.2 (15 %)9.3 (12 %)
10 %66.3 (77 %)37.9 (47 %)66.8 (78 %)2.9 (4 %)2.9 (4 %)

Page load, 100 KB

Median seconds over 60 requests (20 per run). Lower is better.

Loss, each wayNo VPNHysteria2VLESS RealityWireGuardOpenVPN (UDP)
0 %0.39 s0.08 s0.48 s0.53 s0.56 s
1 %0.40 s0.15 s0.51 s0.59 s0.61 s
5 %0.52 s0.16 s0.67 s0.65 s0.72 s
10 %0.60 s0.23 s0.80 s0.90 s1.08 s

Setup

Germany ↔ Netherlands (about 36 ms apart), +20 ms delay each way, 100 Mbit/s cap, random loss in both directions; test website on BBR (host default); 3 runs per loss level in shuffled order; page load = 60 requests of 100 KB.

Two Linux servers, one acting as the client and one running the VPN servers and a small test website. The poor network is made with Linux tc netem on the client: the same loss, delay and speed cap apply in both directions, and only to packets exchanged with the lab server. Loss is per direction, so 5 % each way is roughly 10 % over a round trip.

ProtocolCarried overHow it carries traffic
WireGuardUDPIP tunnel: your own TCP connections travel inside it end to end.
OpenVPN (UDP mode)UDPIP tunnel, the same idea as WireGuard.
VLESS RealityTCPProxy: TCP ends at the VPN server and is re-sent over one TLS-looking TCP connection.
Hysteria2QUIC (UDP)Proxy over QUIC with its own congestion control.
No VPN—Reference: the same request without a tunnel.

All protocols run with standard, documented settings; none gets special tuning. Hysteria2 runs without bandwidth hints, its default, in which case it uses BBR.

What was measured

  • Download speed: one 64 MB file, capped at 20 seconds, average Mbit/s.
  • Page loads: twenty requests of 100 KB per run, each with a 10-second timeout. Every load time is recorded and failures are counted. This is closer to how browsing feels than a speed test.
  • Every loss level and protocol was run three times, in shuffled order; the tables show medians.

Reading the results

Why the IP tunnels fall so far. WireGuard and OpenVPN do not recover lost packets; the TCP connection inside the tunnel has to, end to end, across the whole lossy path. VLESS Reality ends your TCP connection at the VPN server, so recovery happens on the server's own TCP connection, and Hysteria2 recovers losses inside QUIC with its own congestion control.

Why Hysteria2's pages load so fast. Mostly because QUIC keeps one connection open and opens a new stream per request, while the other paths start a fresh TCP connection for every request — and, for VLESS Reality, a fresh Reality handshake too. It is a property of connection reuse as much as of loss handling.

Hysteria2 at 10 %. It kept 91 % of its speed at 5 % loss but 47 % at 10 %, while VLESS Reality kept 78 %. This run shows the drop, not its cause.

Limits — read before quoting

  • The test website used BBR (the host default). Inside WireGuard and OpenVPN your TCP connection is controlled by the website's server, and BBR shrugs off random loss far better than CUBIC, the Linux default. This is the most forgiving case for TCP inside a tunnel; with CUBIC the tunnel numbers can be lower.
  • Loss was random and independent. Real Wi-Fi and mobile loss often comes in bursts, which can change the ranking.
  • One route, one pair of servers. Other distances, CPUs or providers give other absolute numbers. Compare protocols within this run, not with numbers from another setup.
  • This is not a censorship test. Every protocol was allowed through. How they behave when UDP is blocked or traffic is inspected is what the continuous measurements and later experiments are for.
  • Speed was capped at 100 Mbit/s on purpose, so the test measures behaviour, not server CPU.

Failed runs

One OpenVPN download at 1 % loss and one VLESS Reality download at 5 % loss failed to start. They are counted as 0 Mbit/s; with three runs per cell the medians are unaffected. A handful of page requests failed at 1 % and 10 %; they are in the raw data.

Repeat it

The scripts install the servers, apply the network conditions, run the measurement loop and summarise the results. You need two Linux servers, ideally in different cities; a full run takes about an hour. Everything is at github.com/colitu/vpn-lab (scripts under the MIT licence), and the raw results of this run are in results/ep01-packet-loss.jsonl.

The experiment measures how protocols behave, not which VPN provider is better. Colitu's apps switch between protocols automatically when a network gets bad, which is why we care how each one survives. See the methodology on what that means for our results.