Everyday use

Why your VPN speed test comparison is meaningless

7 min read

You ran a speed test without the tunnel, ran it again with the tunnel, and the second number was lower. Before concluding anything, look at what those two runs did. They almost certainly talked to two different machines, in two different cities, minutes apart. That is not a before-and-after. It is two unrelated experiments reporting the same unit.

What a browser speed test actually does

A speed test in a browser answers one question — how much capacity does this line have right now — and makes three design choices to answer it well.

  • It opens several TCP connections at once and adds up their throughput. One connection ramps up slowly and gives back rate on every loss; several in parallel fill a fast line more reliably. Measurement work settled on four as a practical minimum, and tests commonly use eight or more.
  • It measures a short burst — ten to fifteen seconds per direction, often cut short once the rate looks stable.
  • It picks the server for you: a shortlist of hosts near wherever your address appears to be, then whichever of them answers fastest.

Each choice is right for that question. None of them describes what one download, one call, or one page load will do.

The target moves when the exit moves

Server selection is what quietly breaks the comparison. The test reads your public address, decides roughly where you are, and offers the nearest server. Change the exit and that address changes, so the test re-runs the logic and lands somewhere else. Your second measurement differs from the first in four ways: a different server, a different distance, a different set of transit networks, different load on both ends. The tunnel is one variable out of four.

If the test named one city before and another after, the comparison is already uninterpretable. Pin the server by hand — most tests let you — or there is nothing to compare.

Latency is the number you feel

The number in the largest font is throughput. The one that decides how a connection feels is round-trip latency. Loading a page is not one transfer but a chain of dependent round trips — DNS, the TCP handshake, the TLS handshake, the HTML, then everything the HTML references. Each link waits a full RTT, so 40 ms added to the path gets paid several times before the first pixel appears. In a call or a game, latency is the delay, and spare bandwidth does not remove it.

Part of it is physics. Light in fiber covers roughly 200 km per millisecond, so every 1000 km of distance costs about 10 ms of round trip before any equipment touches the packet. A distant exit is a cost you chose, not a defect to tune away.

Record two latency numbers, not one. Idle RTT tells you about distance. RTT measured while the link is saturated tells you whether a large upload will wreck a call sharing the same buffer — the case where the test reads fine and the call breaks up.

One stream is not eight streams

The gap between the headline figure and a single large download is the bandwidth-delay product. A TCP flow can have only one window of unacknowledged data in flight, so its ceiling is window size divided by RTT. Stacks autotune the window, but the ceiling is real and it falls as RTT rises.

Loss compounds the gap: one loss event cuts a single flow's rate hard, while eight parallel flows give up a fraction of their aggregate and recover faster. A file download can land far below what the parallel test just reported over the same path.

Measure both. Single-stream throughput predicts a download or a backup. Multi-stream throughput predicts a browser assembling a busy page. Reporting one of them and calling it "speed" is the original error.

A comparison that means something

  1. 1Fix the target: one test server chosen manually, or one large file from a host that is not going anywhere.
  2. 2Record the whole set each run — idle RTT, RTT under load, packet loss, single-stream throughput, multi-stream throughput.
  3. 3Alternate conditions in one short window: direct, tunnel, direct, tunnel, within ten minutes. Conditions drift; alternating cancels most of the drift.
  4. 4Take at least three runs per condition and compare medians, not the best run.
  5. 5Note the time of day, and repeat on another day before believing the result.

If the tunnel costs 15 ms of RTT and a fifth of your single-stream throughput, over a cable, at 3 a.m. and again at 9 p.m. — that is a finding. "Half my speed," from one test against two different servers, is not a measurement.

Rule out the confounders first

  • Wi-Fi. A shared half-duplex radio with neighbors on the same channel is the most common bottleneck there is, and it changes minute to minute. Test over a cable.
  • Client CPU. Tunnel crypto runs on your own processor, and some clients do it in userspace on one thread. A core pinned at 100% through the whole test is your speed limit, not the network.
  • The router. A consumer router terminating the tunnel itself often lands far below its routed throughput: the hardware acceleration behind that headline figure does not apply to tunnel traffic.
  • Time of day. Transit links serving an exit have peak hours. The same exit can be clean at noon and congested at 9 p.m.
  • Your own network. A phone uploading photos or a console pulling an update shares the link.
  • Packet size. If large transfers stall while small requests fly, that is fragmentation, not slowness — see MTU and fragmentation.

Encryption itself is rarely the headline cost. Devices with AES acceleration, and the ChaCha-based ciphers used where it is absent, move data faster than most access links. Cipher choice matters when a core is pinned; trading protection for a benchmark number does not.

Path problem or tunnel problem

When the numbers survive that scrutiny, ask where the loss happens. A hop-by-hop tool — mtr on Linux and macOS, WinMTR or the built-in pathping on Windows — separates the path from the tunnel. Run it twice: outside the tunnel toward the server's address, then with the tunnel up toward a stable destination beyond it. Give each run a few hundred packets.

  • Loss at one middle hop that vanishes at the next hop is not loss. Routers deprioritize probes addressed to themselves while forwarding traffic at line rate, and the drop is cosmetic.
  • Loss that starts at a hop and continues to the destination is real, beginning at the first hop where it appears.
  • A latency step that persists through every later hop is genuine added delay; a spike with normal numbers after it is the same artifact.
  • A clean path to the exit plus a slow tunnel points at the endpoints — your client, its CPU, its configuration, or load on the server.

Two mtr runs, three alternating pairs against one fixed target, a note of the time: five minutes, and the answer is defensible.

Is a browser speed test useless, then?

No. It answers the question it was built for: the capacity of your access line toward a nearby, well-connected server. It misleads as a before-and-after across two exits, because it silently changed its own target between runs.

How much slowdown should I expect from a tunnel?

There is no honest single figure. It depends on the added distance, the transit path between exit and destination, the protocol, load on the server, and your own hardware. Anyone quoting a fixed percentage is quoting a number measured on somebody else's path.

Why is my download slower than the speed test said?

A speed test adds up several parallel connections; a download is usually one. A single flow is capped by its window divided by the round-trip time and gives up more rate on each loss, so it can land well below the aggregate figure with nothing broken.

My ping went up but throughput barely moved. Which matters?

For calls, games, and how fast a page starts rendering, the added round-trip time is what you notice; for large transfers, throughput is. Higher RTT also lowers the ceiling of any single connection, so it shows up in single-stream downloads even when parallel tests look unchanged.

Did this help?

Nothing follows from the answer; only we see it.

Send this to someone

Useful to anyone with the same problem.