Abstract
A connection-quality system built around evidence boundaries.
Network Diagnostics Suite began as a browser test for throughput and latency under load. It became a shared measurement system after the browser’s limits, disagreements with M-Lab, and the need for operating-system evidence made a single-client design inadequate.
01
From speed test to diagnostic system
The project began with a practical question: why can a fast connection still feel bad?
Ordinary speed tests compress a connection into download and upload headlines. Those numbers matter, but they do not show whether latency rises during transfer, whether one flow behaves differently from several, whether the result is still ramping, or whether failures occur around an otherwise healthy average.
The browser application therefore measured idle latency, loaded latency during download and upload, latency distributions, jitter, request failures, single-flow and aggregate throughput, and connection-count scaling. The design kept the barrier to entry low: no installation, account, telemetry, or project-operated result database.
That browser-first scope exposed the next problem. Several questions users naturally ask—packet loss, gateway health, traceroute, DNS resolver timing, route choice, Wi-Fi condition, path MTU, and local-link capacity—cannot be answered truthfully by webpage JavaScript. The architecture expanded instead of relabeling browser approximations.
Browser
Immediate connection quality
First-party transfer, responsiveness under load, request loss, scaling, endpoint selection, and locally stored reports.
Desktop
Native diagnostic workbench
Connection Check, Quick, Full, and Stress plus operating-system, interface, route, resolver, path, and local area network (LAN) evidence.
CLI
Scriptable deep probe
Repeatable Internet Control Message Protocol (ICMP), traceroute, Domain Name System (DNS), Maximum Transmission Unit (MTU), TCP/TLS, Wi-Fi, routing, optional Internet transfer, and two-machine LAN testing.
Report
Compatible evidence envelope
Schema 2.0 carries producer identity, plan, endpoint context, measurements, findings, and optional native or LAN sections.
02
The browser boundary
A browser can measure application behavior precisely without having raw network visibility.
Idle latency uses uncached requests to the project’s ping endpoint. Successful requests produce minimum, maximum, mean, median, 95th percentile, and consecutive-sample jitter. Failed or timed-out requests divided by attempts produce browser request loss.
That value is not packet loss. Transmission Control Protocol may retransmit below the browser, while failures can originate in Domain Name System resolution, Transport Layer Security setup, HTTP handling, extensions, browser scheduling, endpoint behavior, or the path itself. The browser cannot isolate those layers.
The same boundary excludes truthful traceroute, default-gateway testing, route-table inspection, raw ICMP, path Maximum Transmission Unit discovery, source-interface socket binding, and reliable Wi-Fi radio details. Rather than invent those fields, the project added a native core and made capability status part of the report.
03
Benchmarking against the M-Lab test used by Google Search
A large download gap became evidence that the test might be measuring its own delivery path.
Early comparisons repeatedly showed M-Lab reporting much higher download speed while upload stayed close. One observed pair was approximately 381 Mbps through M-Lab versus 182 Mbps through Network Diagnostics Suite. A later comparison showed 328.7 Mbps down and 86.2 Mbps up through M-Lab, versus roughly 198–206 Mbps down and 85–91 Mbps up through the project.[2][4]
The close upload values mattered. They weakened the idea that the browser, access connection, or all Cloudflare traffic was universally capped near 200 Mbps. The discrepancy was concentrated in the project’s download implementation.
Research into Network Diagnostic Tool version 7 (NDT7) corrected another assumption: M-Lab was not simply opening many parallel browser downloads. NDT7 uses one long-lived WebSocket over one TCP connection, usually to a nearby well-provisioned server, with Bottleneck Bandwidth and Round-trip propagation time (BBR) where available and server-side TCP instrumentation. It measures application-level goodput over a mature measurement path.[1][3]
| Development observation | M-Lab | Network Diagnostics Suite | Interpretation |
|---|---|---|---|
| Early comparison | ≈381 Mbps down | ≈182 Mbps down | The gap was too large to dismiss without isolating the serving path. |
| Later comparison | 328.7 down / 86.2 up | ≈198–206 down / 85–91 up | Upload agreement pointed toward a download-specific bottleneck. |
| Post-change observation | Not run concurrently | ≈370.1 median / 366.3 steady down | The earlier 180–200 Mbps ceiling was not an unavoidable browser limit. |
Evidence boundary: these values were retained from back-to-back development testing, not a controlled benchmark dataset. The earliest observations did not preserve exact timestamps, browser build, device configuration, selected M-Lab server, or exported reports. They are included as engineering observations; the project-controlled R2-versus-Worker A/B below is the stronger causal evidence.
04
Finding the download bottleneck
The clearest experiment compared the connection through two project-controlled delivery paths.
The initial engine repeatedly requested a dynamically composed Worker stream. Even with cache hits, concurrency, and modern protocol negotiation, throughput oscillated and frequently settled near 200 Mbps. Request turnover could create brief peaks without sustaining the same rate.
The project then added a large deterministic incompressible object on a direct R2 custom domain while retaining the Worker stream as an explicit comparison. The direct path delivered 283.2 Mbps whole-phase and 270.9 Mbps steady, while the Worker path delivered 159.7 Mbps whole-phase and 157.9 Mbps steady. Upload remained around 97 Mbps through either route. Cloudflare’s cache and range-request documentation informed the direct delivery design.[6][7]
That A/B result showed the project’s own Worker path materially limiting download delivery. The browser was measuring both the user’s connection and avoidable server-side response construction.
6ed3cdbMove download testing to first-party static edge assets
Introduced deterministic static payloads, an excluded warm-up, and a Worker fallback.
4bacb7eUse long-lived segmented Worker responses
Reduced routine request turnover and recorded request generations and lifecycle evidence.
7b27ea8Add direct R2 download A/B path
Added direct range delivery, validation, cache evidence, and explicit Worker comparison.
8ec174dMake automatic R2 delivery the default
Retained Worker delivery as a fallback and advanced comparison rather than an assumed equivalent.
The goal was not to force the same number as M-Lab. It was to remove project-created bottlenecks so that disagreement reflected methodology and path differences rather than an inefficient payload implementation.
05
A shared measurement plan
Profiles became contracts rather than loose labels for roughly how long a test runs.
The browser, desktop application, and opt-in CLI Internet-transfer mode consume the same canonical profile contract. It defines idle samples, stage duration, byte ceilings, sample count, aggregate connection count, service checks, comparison allocation, and Stress scaling stages.[9]
Single uses one connection in each direction. Aggregate uses the profile’s configured parallel connection count. Compare runs independent single and aggregate stages so the methods do not compete. Stress measures download scaling at 1, 2, 4, 8, and 10 connections before upload comparison.
Each client computes the actual stage sequence, estimated time, and maximum transfer before starting. Caps are ceilings, not promised consumption. A slower connection reaches the duration first; a fast connection may reach the byte ceiling first.
| Profile | Base estimate | Download cap | Upload cap | Deep diagnostics |
|---|---|---|---|---|
| Connection Check | 15 seconds | 20 MB | 8 MB | No |
| Quick | 20 seconds | 600 MB | 128 MB | No |
| Full | 35 seconds | 900 MB | 256 MB | Yes |
| Stress | 60 seconds | 3 GB | 512 MB | Yes |
06
Throughput and responsiveness
An average stays useful, but the shape of the transfer explains more.
Throughput uses successfully transferred payload bytes over elapsed wall time. Progress is sampled every 250 milliseconds. Intervals shorter than 100 milliseconds are excluded from graph and interval-derived statistics so a few terminal bytes cannot create an impossible peak; those bytes remain in the whole-phase average.
The engine also reports steady-state rate after the initial ramp, retained peak, coefficient of variation, stability, ramp ratio, and classifications such as cap-limited, still-ramping, declining, unstable, or qualified. Multi-sample download stages report medians rather than allowing one outlier to define the profile.
Separate latency requests continue during each transfer stage. Added delay is the loaded median minus the idle median. This shows whether the measured path remains responsive while busy without claiming which router, radio, provider segment, route, or endpoint created the queue.
Single share and parallel gain expose when several flows use materially more of the path than one flow. They do not identify the cause: congestion control, packet loss, endpoint limits, routing, radio conditions, security software, CPU load, and server behavior can all contribute.
Mbps = transferred bytes × 8 ÷ elapsed seconds ÷ 1,000,000
added delay = loaded median - idle median
single share = single steady Mbps ÷ aggregate steady Mbps × 100
parallel gain = (aggregate steady Mbps ÷ single steady Mbps - 1) × 100
07
Endpoint and transport context
A speed result is incomplete without identifying where and how it was measured.
Before a run, the browser and native core probe configured endpoint candidates and select the lowest-latency available origin. Reports preserve candidate success and failure, selected origin, edge location, network name, autonomous system number, negotiated protocol, Transport Layer Security version, and Internet Protocol version when available.[5]
The desktop and CLI can select a source interface. HTTP/1.1, HTTP/2, and LAN sockets bind to the interface’s source address. Managed ICMP, traceroute, DNS, and the exact HTTP/3 request remain routed by the operating system because their portable APIs do not provide equivalent source-interface binding. The report states that scope rather than implying complete isolation.
The native engine sends a separate HTTPS request requiring HTTP version 3.0 exactly. Browsers cannot make an equivalent portable exact-version request, so the web client records the protocol observed through Navigation Timing instead. Observed and forced protocol evidence remain distinct.[8]
08
The native core
Deeper evidence moved into a shared engine instead of being duplicated across a graphical interface and a command line.
NetworkDiagnostics.Core on .NET 10 owns planning, endpoint selection, Internet transfers, ICMP, gateway testing, traceroute, resolver timing, path MTU, TCP and TLS phases, interfaces, Wi-Fi, routes, LAN testing, findings, capability reporting, and serialization.[10]
Avalonia provides the Windows, macOS, and Linux desktop host. The application adds a workbench for profiles, methods, progress, cancellation, comparison, history, import, export, settings, and detailed evidence. The command-line host preserves repeatable deep-only diagnostics and can explicitly opt into the same Internet-transfer plans.
Core
One implementation of native measurement
Planning, transfer enforcement, diagnostics, findings, capabilities, and report serialization.
Desktop
Interactive workbench
Cross-platform native controls, local history, comparison, and evidence-oriented result views.
CLI
Automation and repeatability
Scriptable diagnostics, output paths, interface selection, endpoint overrides, and LAN server/client modes.
Platforms
Five packaged targets
Windows x64, Apple Silicon macOS, Intel macOS, Linux x64, and Linux ARM64.
09
Schema 2.0 and findings parity
Richer evidence did not require incompatible browser and native report silos.
Schema 2.0 is a combined envelope for producer identity, run metadata, transfer plan, endpoint selection, interface scope, network context, Internet measurements, deep diagnostics, optional LAN results, and deterministic findings.
Compatibility remains additive. The browser importer accepts historical native schemas 1.0, 1.1, and 1.2 as well as 2.0. Unknown optional fields are ignored. Missing native sections mean the scope was not run or was unavailable and render as “Not measured,” not failure.
Shared parity fixtures verify that TypeScript and C# findings engines produce the same finding identifiers for representative reports. Rendered wording can remain appropriate to each client while the underlying interpretation does not drift silently.
Imported native JSON is read through the browser File API and parsed locally. It is not uploaded to the project, allowing the browser to act as a compatible report reader without becoming a collection service.
{
"schemaVersion": "2.0",
"producer": { "client": "desktop", "engine": ".NET" },
"plan": { "profile": "full", "method": "compare" },
"context": {
"selectedEndpoint": "...",
"interfaceBinding": "http-and-lan-only",
"http3": { "attempted": true, "negotiated": "h3" }
},
"measurements": {
"internet": { "...": "..." },
"deepDiagnostics": { "...": "..." },
"lan": null
},
"findings": [
{ "id": "loaded-latency-high", "confidence": "high" }
]
}
10
LAN isolation and interface binding
A second trusted machine removes the public Internet without pretending to remove the local endpoints.
The optional LAN server listens on a configurable TCP port. The client measures request/response latency, generated download traffic, and generated upload traffic with a configurable duration and parallel stream count.
This removes the provider, public transit, and public test platform. It does not remove either machine’s operating system, CPU, adapter, firewall, switch, access point, cabling, or TCP implementation. A preferably wired server with capacity above the expected client rate is recommended.
Fast LAN with slower Internet points away from the local link as the primary bottleneck. Slow LAN makes the local device, adapter, radio, cabling, switch, access point, server, or firewall part of the investigation. It narrows scope rather than producing a universal diagnosis.
11
Privacy and accuracy
Privacy is implemented through minimization, while accuracy begins by stating the remaining dependencies.
The project has no accounts, cookies, analytics, advertising, telemetry, or project-operated result database. Browser history remains in that browser. Native reports remain on the user’s computer. Imported reports are not uploaded.
No retained result does not mean invisible traffic. Cloudflare necessarily processes traffic sent to default endpoints. Full and Stress service checks contact the named providers. User-supplied endpoints and LAN targets remain outside the project’s trust boundary.
Native reports hide local interface addresses, gateways, resolver addresses, private route details, hostname, public IP, MAC address, and service set identifier by default. Enabling local identifiers makes the report sensitive diagnostic material.
Every result describes a particular device, software stack, route, endpoint, and moment. Virtual private networks, security software, CPU load, power saving, Wi-Fi contention, browser scheduling, and background traffic can affect a run. Repeated comparisons are more useful than treating one result as a permanent rating.
12
Validation and release engineering
The project’s contracts are useful only when browsers, native targets, and report readers continue to agree.
Continuous integration validates design-system integration, TypeScript, browser and Worker tests, production builds, the native core, deep-probe tests, desktop builds, profile contracts, report compatibility, and findings parity.
Concurrent native download workers reserve bytes before reading so committed measured payload cannot exceed the configured stage ceiling. Cancellation preserves partial evidence rather than converting an interrupted run into an empty failure.
Desktop and CLI workflows package self-contained artifacts for five runtime targets with checksums and local privacy notes. macOS artifacts are valid application bundles but remain unsigned until Developer ID signing and notarization credentials are configured.
Contracts
Profiles and schemas
Shared fixtures prevent browser and native definitions from drifting independently.
Parity
TypeScript and C# findings
Representative reports must produce the same rule identifiers across engines.
Packaging
Five native targets
Self-contained outputs and checksums make artifacts inspectable and reproducible.
Boundaries
Failures remain explicit
Unsupported, unavailable, partial, and cancelled states are preserved rather than guessed away.
13
Lessons and next work
The project’s largest improvements came from treating disagreement as evidence. M-Lab’s higher result was not dismissed as “a different server,” and it was not used as a number that had to be copied. It triggered a transport investigation that revealed a real bottleneck in the project’s Worker delivery path.
The same pattern shaped the rest of the system. Browser request failures were not relabeled as packet loss. A native probe was added. One aggregate throughput number was not treated as the connection’s full capacity. Single, aggregate, and scaling stages were separated. Missing fields were not guessed. Schema compatibility made absence explicit.
Future work should continue in that direction: more controlled cross-client comparison fixtures, signed and notarized desktop packages, broader platform validation of Wi-Fi and route parsers, and longitudinal comparison tools that help users distinguish a temporary route from a persistent local fault.
A useful diagnostic tool does not need to know everything. It needs to make clear what it observed, what it inferred, and what remains unknown.
References
Primary sources and project records
- Measurement Lab, “ndt7 protocol specification.”
- Measurement Lab, “NDT (Network Diagnostic Tool).”
- Measurement Lab, “ndt7 Protocol and data schema.”
- Measurement Lab, “How fast is my Internet? Speed Tests, Accuracy, NDT & M-Lab.”
- Measurement Lab, “Locate API.”
- Cloudflare, “Enable cache in an R2 bucket.”
- Cloudflare, “Default Cache Behavior: client-side range requests.”
- World Wide Web Consortium, “Resource Timing.”
- Network Diagnostics Suite, “Measurement methodology.”
- Network Diagnostics Suite, architecture, profiles, compatibility, privacy, and deployment record.