Two runs, one tunnel, and the numbers differ by a factor of three. The tunnel did not change between them. What changed is the measurement: a test site that selects a server based on your apparent location, a stream count that decides whether one slow start or six are filling the pipe, and a duration short enough to end before the path is even being used properly. Speed tests are not wrong, but they answer a narrower question than the one people ask them.

A new exit address changes the test destination

Most test sites pick a measurement server automatically, and they pick it partly by looking at where your connection appears to come from. Switch the tunnel on and your apparent country changes, so the chosen server changes, and the comparison now spans two different routes to two different hosts.

The result is not a VPN measurement at all. It is a measurement of your path to a server you did not choose, and the difference between the two runs can be dominated by that server's peering rather than by anything the tunnel did.

Fix the destination before changing anything else. Every credible tool lets you pick a server explicitly, and when it does not, the result page usually names the one it used, which is enough to notice that the two runs are not comparable. Confirm what the site saw before you trust the choice it made:

curl -sS https://ipinfo.io/json | grep -E '"ip"|"org"|"country"'

If the country changed between runs, everything the test chose downstream of that changed too. Write the observed exit next to each result and the confusion mostly disappears.

Slow start finishes after most short tests end

A TCP connection does not begin at the link rate. It begins at a small congestion window, doubles it roughly every round trip, and only reaches the path's capacity after several round trips. A ten-second test on a path with high latency can spend a substantial part of its life in that ramp.

That is why a tunnel with more latency scores worse on a short test than it deserves, and why a longer run often reports a higher number with no configuration change. The RFC 6349 throughput framework treats this explicitly, which is why serious measurements run long enough to reach a steady state. A five-second run on a satellite path is measuring the accelerator, not the road.

Look at the connection phases rather than trusting a single number. Curl reports each stage separately, so you can see whether time is going into the handshake, the ramp, or the transfer:

curl -sS -o /dev/null -w 'dns=%{time_namelookup} tcp=%{time_connect} tls=%{time_appconnect} total=%{time_total} bytes/s=%{speed_download}\n' \
  https://mirror.example.net/testfile.bin

Run it twice in a row on the same destination. If the second run is much faster, you were measuring the ramp, not the path, and any comparison that used only the first run is suspect.

One stream and six streams measure different things

A single TCP stream is limited by the window it can keep in flight, which is roughly the round-trip time multiplied by the rate. On a long path that product exceeds what one stream will use, so a single download under-reports the capacity that exists. Six parallel streams fill the gap and produce a bigger number.

iperf3 -c speed.example.net -t 20
iperf3 -c speed.example.net -t 20 -P 6
mtr -rwc 50 speed.example.net

Both numbers are true. The single-stream figure tells you what one download will do, which is what a browser tab usually gets. The parallel figure tells you what the path can carry in aggregate, which is what a torrent or a multi-part download can use. Quoting one as though it were the other is how a healthy tunnel gets replaced for no reason.

Comparing a parallel result against a single-stream result is the most common way people conclude that a VPN halved their speed. Match the method, then compare. The trace in the third command adds the missing context: a path with high jitter will produce inconsistent results in both modes, and no stream count fixes that.

Encryption costs processor time, encapsulation costs bytes

Two mechanisms run on every packet regardless of how fast the link is. Encryption consumes CPU per byte, and encapsulation adds header bytes that the link still has to carry. Both show up as a ceiling, and they have different symptoms.

The CPU ceiling appears as a plateau: throughput stops rising no matter how many streams you add, and the machine's processor is busy while the link is not. On a small router or a phone, that is often the real limit, and it is why a fast line can still deliver a modest tunnel.

The byte cost is smaller but constant. Extra headers mean less payload per packet, and on a path with a fixed maximum transmission unit they can also trigger fragmentation or black-holing that shows up as a stall on large transfers rather than as a slow average.

ObservationLikely mechanismWhat to measure
Throughput flat as streams increaseCPU per packet on one corePer-core utilisation during the test
Fast small transfers, stalled large onesMTU and fragmentationPayload size at which it breaks
Good average, unusable callsQueueing delay behind a full bufferLatency under load

These three are frequently confused because all of them are described by users as "the VPN is slow". Only the first responds to a bigger machine, only the second responds to a smaller MTU, and only the third responds to queue management.

Put the method in the record

A result worth keeping names the device, the access network, the exit, the measurement server, the direction, the stream count and the duration. Without those, two numbers cannot be compared, and a ticket that contains one number is really a mood.

Keep the bad runs too. A series where one exit produces a stall every time is far more informative than an average, and the stalls are exactly what averages hide.

Then test the thing you actually care about. If a large download is the goal, download the file. If a call is the goal, measure latency under load rather than idle throughput, because a tunnel can score well on a speed test and still make every meeting unlistenable.

អត្ថបទពាក់ព័ន្ធ