Skip to main content
The Results object is available as speedTest.results at any point during a test run, and is passed directly to the onFinish callback when all measurements are complete. Every method returns undefined (or an empty array) if the relevant measurement has not yet started or has been excluded from the measurement sequence.

Attribute

isFinished
boolean
required
true when every measurement in the configured sequence has completed. Equivalent to checking SpeedTestEngine.isFinished. Use this to gate calls to getScores(), which requires all measurements to be done.

Bandwidth

getDownloadBandwidth()

Returns the computed download bandwidth in bits per second (bps). The value is the configured percentile (default: 90th) of all individual request measurements whose duration exceeded bandwidthMinRequestDuration (default: 10 ms). Returns number | undefined. undefined is returned if no qualifying download measurements have completed yet.
import SpeedTest from '@cloudflare/speedtest';

const engine = new SpeedTest({ autoStart: false });

engine.onResultsChange = () => {
  const bps = engine.results.getDownloadBandwidth();
  if (bps !== undefined) {
    const mbps = bps / 1e6;
    console.log(`Download: ${mbps.toFixed(1)} Mbps`);
  }
};

engine.play();

getDownloadBandwidthPoints()

Returns all individual download measurements as an array of BandwidthPoint objects. Useful for drawing a live chart of throughput over time. Returns BandwidthPoint[].
BandwidthPoint
object
const points = engine.results.getDownloadBandwidthPoints();

points.forEach(({ bytes, bps, duration }) => {
  console.log(`${bytes / 1e6} MB payload — ${(bps / 1e6).toFixed(2)} Mbps in ${duration.toFixed(0)} ms`);
});

getUploadBandwidth()

Returns the computed upload bandwidth in bps. Same calculation and semantics as getDownloadBandwidth(). Returns number | undefined.

getUploadBandwidthPoints()

Returns all individual upload measurements. Same shape as getDownloadBandwidthPoints(). Returns BandwidthPoint[].
To convert bps to Mbps, divide by 1e6. To convert to Kbps, divide by 1e3.
const mbps = (engine.results.getDownloadBandwidth() ?? 0) / 1e6;

Latency

All latency values are in milliseconds. The reported latency is the configured percentile of all measurements (default: median / 50th percentile, set by latencyPercentile).

Unloaded latency

Measured by dedicated latency-type requests against the download API with bytes=0 while no other activity is taking place.
const latency = engine.results.getUnloadedLatency();   // number | undefined
const jitter  = engine.results.getUnloadedJitter();    // number | undefined
const points  = engine.results.getUnloadedLatencyPoints(); // number[]
getUnloadedLatency()
number | undefined
The median (or configured percentile) round-trip latency at idle, in ms.
getUnloadedJitter()
number | undefined
Average absolute difference between consecutive latency measurements, in ms. Requires at least two latency measurements.
getUnloadedLatencyPoints()
number[]
All raw latency values in measurement order. Each entry is a single ping value in ms.

Loaded latency (download direction)

Measured simultaneously with download requests. Requires measureDownloadLoadedLatency: true (default).
const dlLatency = engine.results.getDownLoadedLatency();       // number | undefined
const dlJitter  = engine.results.getDownLoadedJitter();        // number | undefined
const dlPoints  = engine.results.getDownLoadedLatencyPoints(); // number[]
getDownLoadedLatency()
number | undefined
Latency observed while the connection is saturated with download traffic, in ms. Only includes samples from requests that lasted longer than loadedRequestMinDuration (default: 250 ms).
getDownLoadedJitter()
number | undefined
Jitter during download load, in ms.
getDownLoadedLatencyPoints()
number[]
All raw loaded-latency samples from the download phase, capped at loadedLatencyMaxPoints (default: 20). Latest samples are kept, as they are considered most accurate.

Loaded latency (upload direction)

Measured simultaneously with upload requests. Requires measureUploadLoadedLatency: true (default).
const ulLatency = engine.results.getUpLoadedLatency();       // number | undefined
const ulJitter  = engine.results.getUpLoadedJitter();        // number | undefined
const ulPoints  = engine.results.getUpLoadedLatencyPoints(); // number[]
getUpLoadedLatency()
number | undefined
Latency observed while the connection is saturated with upload traffic, in ms.
getUpLoadedJitter()
number | undefined
Jitter during upload load, in ms.
getUpLoadedLatencyPoints()
number[]
All raw loaded-latency samples from the upload phase.
Loaded latency is typically higher than unloaded latency. The difference between the two is used when calculating AIM scores — a large increase under load indicates a connection more prone to bufferbloat.

Packet loss

Packet loss requires a WebRTC TURN server. You must provide your own TURN credentials — the public Cloudflare TURN server is deprecated. See Packet Loss for setup instructions.

getPacketLoss()

Returns the packet loss ratio as a number between 0 and 1. Multiply by 100 for a percentage. Returns number | undefined. Returns undefined if no packetLoss measurement was configured or has not yet started.
const loss = engine.results.getPacketLoss();

if (loss !== undefined) {
  console.log(`Packet loss: ${(loss * 100).toFixed(2)}%`);
}

getPacketLossDetails()

Returns the full packet loss result object, or an error object if the TURN connection failed.
getPacketLossDetails()
object | undefined
const details = engine.results.getPacketLossDetails();

if (details && 'error' in details) {
  console.error('Packet loss measurement failed:', details.error);
} else if (details) {
  const { packetLoss, numMessagesSent, lostMessages } = details;
  console.log(`Sent ${numMessagesSent} packets, lost ${lostMessages.length}`);
  console.log(`Loss rate: ${(packetLoss * 100).toFixed(2)}%`);
}

Summary

getSummary()

Returns a single object aggregating all available metrics. Keys are only present when their measurement was performed and produced a result. See Summary for full documentation.
engine.onFinish = results => {
  const summary = results.getSummary();
  console.log(summary);
  // {
  //   download: 94500000,
  //   upload: 21300000,
  //   latency: 12,
  //   jitter: 1.4,
  //   downLoadedLatency: 38,
  //   downLoadedJitter: 4.2,
  //   upLoadedLatency: 29,
  //   upLoadedJitter: 3.1,
  //   packetLoss: 0
  // }
};

Build docs developers (and LLMs) love