A Rust client library and CLI for ndt7, the network speed test protocol developed by M-Lab.
ndt7 measures download and upload throughput using WebSocket connections to M-Lab's global server infrastructure, providing TCP-level metrics (latency, retransmission) alongside application-level throughput.
use ndt7_client::client::ClientBuilder;
use ndt7_client::spec::Origin;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut client = ClientBuilder::new("my-app", "0.1.0").build();
// Run download test (auto-locates nearest M-Lab server with retry)
let handle = client.start_download(None).await?;
println!("Connected to {}", handle.server_fqdn);
let mut rx = handle.rx;
while let Some(result) = rx.recv().await {
let m = result?;
if m.origin == Some(Origin::Client) {
if let Some(app) = &m.app_info {
let mbps = 8.0 * app.num_bytes as f64 / app.elapsed_time as f64;
println!("Download: {mbps:.1} Mbit/s");
}
}
}
// Run upload test (reuses cached server list)
let handle = client.start_upload(None).await?;
let mut rx = handle.rx;
while let Some(result) = rx.recv().await {
let m = result?;
if m.origin == Some(Origin::Server) {
if let Some(tcp) = &m.tcp_info {
if let (Some(received), Some(elapsed)) =
(tcp.bytes_received, tcp.elapsed_time)
{
let mbps = 8.0 * received as f64 / elapsed as f64;
println!("Upload: {mbps:.1} Mbit/s");
}
}
}
}
Ok(())
}Install:
Pre-built binaries for Linux, macOS, Windows, and illumos are available on the GitHub releases page.
Or install from crates.io:
cargo install ndt7-clientRun a speed test:
$ ndt7-client
Download in progress with mlab2-hnd02.mlab-oti.measurement-lab.org
Avg. speed: 1456.0 Mbit/s
Download: complete
Upload in progress with mlab2-hnd02.mlab-oti.measurement-lab.org
Avg. speed: 1734.5 Mbit/s
Upload: complete
Test results
Server: mlab2-hnd02.mlab-oti.measurement-lab.org
Client: 2001:db8::1
Download
Throughput: 1456.0 Mbit/s
Latency: 3.0 ms
Retransmission: 0.5 %
Upload
Throughput: 1734.5 Mbit/s
Latency: 3.3 msOptions:
--server [<SERVER>] Server hostname. With --no-locate: connect directly (e.g. localhost:8080). Without --no-locate: select this server via locate API (gets access tokens). With no value: interactive server picker
--service-url <SERVICE_URL> Full service URL with path and access token. For advanced use / scripting
--no-locate Skip locate API, connect directly to the server specified by --server
--no-tls Use unencrypted WebSocket (ws://) instead of TLS (wss://)
--format <FORMAT> Output format to use: 'human' or 'json' for batch processing [default: human] [possible values: human, json]
--no-download Skip download measurement
--no-upload Skip upload measurement
--quiet Emit summary and errors only
--no-verify Skip tls certificate verification
--list-servers List available target servers and exit
--ipv4 Force IPv4 connections
--ipv6 Force IPv6 connections
--help Print help
- M-Lab - Measurement Lab
- ndt7 protocol spec
- ndt7-client-go - Go reference implementation
Apache-2.0