Methodology

Methodology

Everything this site does to produce a number, and everything it cannot do. Written for people who want to check the method rather than trust it.

What the test talks to

By default the browser measures against Cloudflare's public measurement endpoints (speed.cloudflare.com), the same endpoints that power Cloudflare's own MIT-licensed speed test. They answer with Access-Control-Allow-Origin: *, so no key, account or proxy is needed.

  • GET /__down?bytes=N — returns exactly N bytes of data for download measurement.
  • POST /__up — accepts a payload and discards it, for upload measurement.
  • GET /__down?bytes=0 — an empty response, used for latency probes.
  • GET /meta — IP address, operator and edge location, requested with this site as the referrer.

Deployments that prefer to measure against their own infrastructure can switch ENGINE.provider to librespeed in src/config.mjs and point it at a self-hosted LibreSpeed backend (LGPL-3.0). The measurement code for that path is included.

When a direct request is blocked

Some networks block cross-origin requests to the measurement host. The engine then tries this site's own /api/measure passthrough, which forwards only the three measurement paths and caps transfer sizes. That passthrough is optional: it needs a small server-side function, so a deployment served as plain static files does not have it. Where it is absent, a blocked direct request fails visibly rather than silently producing a number. When the proxy route is active the result page says so, because a proxy adds a hop and slightly changes the measurement.

Download measurement

Transfers start at 2 MB and scale with the observed speed. Each transfer records a monotonic timeline of received bytes from the ReadableStream reader. The opening part of every transfer is excluded to remove TCP slow-start and TLS setup: for downloads that is the first min(300 ms, 30% of the transfer), so a very short transfer loses proportionally less. The byte count is interpolated at the cut-off, so no data is silently discarded.

The reported figure is a byte-weighted average of the last two stable transfers. The run stops early when two consecutive transfers agree within 8% (10% for upload), or when the data budget is reached, whichever comes first.

Single vs Multi. By default the test uses one TCP connection (Single). Choosing Multi opens four parallel transfers whose bytes are aggregated over wall-clock time, which can saturate a path that a lone stream cannot fill. The mode is stored on your device and shown with the connection details.

Upload measurement

Payloads are pseudorandom so that compression in the path cannot reduce the bytes actually transferred. Upload progress comes from XMLHttpRequest events, which are coarser than download streams; the timeline therefore starts at zero, the target ramp is 400 ms, and in every case the excluded window is capped at 40% of the transfer duration. When a fast link reports the whole payload in a single event, the tool falls back to the full-transfer rate rather than reporting zero. Multi mode uses the same four-stream aggregation as download.

Latency and jitter

Fifteen sequential probes of an empty response, with an overall 7-second ceiling — on a slow path fewer than fifteen may be taken. The first two are discarded while the connection warms up. Where the response carries a Server-Timing header, the server's own reported processing time is subtracted so the figure reflects the network path rather than the endpoint's work.

  • Ping — the median of the remaining samples.
  • Jitter — the mean absolute difference between consecutive samples.
  • p95 — reported on latency-focused pages to show tail behaviour.

These figures include browser scheduling and HTTP processing on both ends. They are not ICMP echo times and should not be compared directly with a game's displayed ping.

One property of these definitions is worth knowing: jitter is not bounded by ping. Jitter is the mean change between consecutive samples, so a run whose samples mostly sit near the median but spike once or twice can report a jitter larger than its ping. That is not an error — it is a sign of an uneven path, and it is exactly what a call or a game would feel. If the two disagree sharply, treat the jitter as the warning.

Bufferbloat grading

Idle latency is measured first, then latency is sampled while a download saturates the line, then again while uploads saturate it. The grade comes from the larger of the two increases over idle: A under 30 ms, B under 60 ms, C under 100 ms, D under 200 ms, F at or above 200 ms. The test reports the idle, download-loaded and upload-loaded figures separately so the grade can be checked.

What the number describes

A result describes the path between your browser and the measurement endpoint that served the request — not the internet in general.

  • It is a measurement of one route. Your traffic takes a specific path to a specific edge. Another website, game server or streaming service may be reached by a different route and perform differently, in either direction.
  • The edge matters. Cloudflare routes your request to a nearby edge data centre using anycast. That is deliberate — it keeps the path short so the result reflects your access line rather than a long detour — but it means the result is influenced by where that edge is and how your ISP peers with it. A user in a different city, or on the same ISP but a different route, can legitimately get a different number.
  • It is not a guarantee of your plan. Advertised speeds describe an access line under conditions no browser can reproduce. A result below the advertised figure is not by itself proof of a fault, and a result at the advertised figure does not promise performance to any particular service.
  • It is a snapshot. Shared networks vary by time of day, by what else is transferring, and by wireless conditions.

Direct measurements, derived figures and browser limits

Not everything on a result page has the same status. The distinction matters when you compare numbers with another tool.

FigureStatusWhat that means
Download, uploadDirectBytes counted as they crossed the network, divided by the time they took, using the ramp handling described above.
PingDirect, HTTP-levelRound-trip time of real requests, less the endpoint's own reported processing time. Not ICMP.
JitterDerivedComputed from the spread between consecutive ping samples — a statistic about those samples, not a separate probe.
p95 latencyDerivedA percentile of the same samples. Meaningful only when enough samples were collected.
Bufferbloat gradeDerivedComputed from idle latency versus latency measured while the line is saturated. The three underlying figures are shown so the grade can be checked.
IP, operator, edgeReported by the endpointReturned by the measurement service, and shown as it arrives. It is not measured by us and is not used in any score.
ConnectionsSingle or MultiSingle uses one TCP stream; Multi opens four parallel streams so a fast path can be filled more fully. Wi-Fi versus Ethernet is not reported — most browsers never expose it — so the control focuses on a setting that changes the measurement.
Packet lossNot measurable hereA browser cannot see dropped packets. The packet-loss page measures failed requests instead and says so.

How much data a test transfers

This is an estimate. The amount depends on your line speed, because the test stops as soon as two transfers agree and a fast connection moves more data in the same fixed time.

The engine is configured with hard ceilings of 60 MB for the download stage and 40 MB for the upload stage — at most about 100 MB for a full run, and usually less. A slow or lossy line transfers considerably less, because the stage ends on its time budget first.

For calibration: our own verification run on a fast connection transferred 60.02 MB of download data in a single test before reaching the 60 MB ceiling. Treat "tens of megabytes" as the honest expectation, and the ceilings above as the upper limit.

Latency-only tools use a few hundred kilobytes. The bufferbloat test transfers the most, because it deliberately saturates the line twice. On a metered or mobile connection, check before running a full test — the homepage states the cost before it starts.

When a measurement fails

The rule is that a number appears only if it was measured. There is no fallback value, no cached estimate and no plausible-looking placeholder.

  • The endpoint is unreachable or refuses the request. The test stops and the page shows the reason. Metric fields stay empty; they are not set to zero, because zero is a measurement and "we could not measure" is not.
  • The run is cancelled. In-flight requests are aborted and the partial numbers are discarded rather than presented as a result.
  • A stage times out. Each stage has a time budget. When it expires with usable samples the stage ends with what it measured; when it expires with nothing usable the test fails as above.
  • The connection metadata is unavailable. The connection bar shows Unavailable for the affected field and the measurement itself continues — metadata is not required to produce a result.
  • Your browser cannot run the test at all. The page says so before starting, and offers the interface preview with sample data, clearly labelled as not a measurement.

What we do not claim

  • No packet-loss figure from the browser. The packet-loss page measures request loss and says so.
  • No in-game server ping. The gaming page measures your line's latency profile and explains the difference.
  • No invented numbers. Before a measurement exists, results show a dash. When a measurement fails, the page shows the error instead of a plausible-looking value.
  • No result storage. Measurements stay in your browser; shared links contain only four numbers and a timestamp.

Questions

How often should I run a speed test?
Once when everything works well, so you have a baseline, and again when something feels slow. Comparing against your own baseline is far more useful than comparing against other people.
Why does the result change between runs?
Networks are shared and dynamic. Expect a few percent variation; larger swings usually mean congestion, Wi-Fi interference or a background transfer.
Can I use these results to complain to my ISP?
Yes, and repeatability helps. Run three tests over Ethernet at different times, keep the timestamps, and note whether the shortfall is consistent or only at peak hours.