Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
speed-cli
This tool provides comprehensive network performance measurements across TCP, UDP, and HTTP protocols. Built with Rust, the test suite optimizes for maximum throughput to measure the network's available bandwidth.
Why Another Network Testing Tool?
It's difficult to have one tool that tests your network conditions between two devices in a way that is representative of real-world traffic. Most tools focus and excel at specific aspects (e.g. iperf3 with TCP/UDP, speed test cools for HTTP throughput/latency). However, applications use a mixture of protocols with various characteristics. This tool is a framework to create synthetic but realistic network loads between any two devices, on any platform using Rust.
Features
- Multi-protocol support: TCP, UDP, raw QUIC, HTTP/1.1, HTTP/2, h2c, HTTP/3
- High-performance: Built with Rust, optimized for high throughput and efficient resource usage
- Comprehensive metrics: throughput (goodput/wire), latency percentiles, jitter, packet loss
- WiFi / latency-under-load stress test: probes latency while saturating the link, detects spikes, and graphs latency over time (terminal + HTML)
- Exporting: CBOR for re-importable data; HTML for self-contained rendered reports
- Cross-platform: Optimized for popular platforms (Linux, macOS, Windows) and architectures (x86_64, ARM)
Installation
Homebrew (macOS / Linux)
crates.io (cargo install)
Requires a Rust toolchain (install via rustup).
RUSTFLAGS="--cfg reqwest_unstable"
The
RUSTFLAGSis required and not optional: speed-cli enables reqwest's HTTP/3 client, which reqwest gates behind thereqwest_unstablecfg. Without it the build fails fast with a message telling you to set exactly this flag. (When building from a clone the repo's.cargo/config.tomlsets it for you — see From source — butcargo installdoesn't read that file.)
Prebuilt binaries
No toolchain needed. Download a binary for your platform from the
latest release —
Linux/macOS tarballs and Windows zips, each with a SHA-256 checksum. Extract it
and put speed-cli on your PATH.
From source
# Prerequisite: Rust installed via rustup (https://rustup.rs/).
# Cloning and building from the repo picks up .cargo/config.toml automatically,
# so no RUSTFLAGS is needed here:
# Installing straight from git does NOT read that config, so set the cfg yourself:
RUSTFLAGS="--cfg reqwest_unstable"
The binary name is speed-cli. Note, for the HTTPS server, you may provide your own TLS certificate and key files via --cert and --key, or else a dummy cert will be used. A convenience script ./gen-cert.sh is provided to generate self-signed certificates for testing purposes. This is not suitable for production use.
Note on HTTPS measurements: the client always skips TLS certificate validation (
danger_accept_invalid_certs) so that self-signed test servers work out of the box. Reported HTTPS throughput and latency therefore exclude the cost of certificate-chain verification, OCSP, and revocation checks. If you need numbers that reflect production TLS overhead, validate against a real cert with another tool.
Quick Start
Note: If you're using HTTPS server, ensure you have cert.pem and key.pem files in the current directory or specify them with --cert and --key flags.
The server publishes a single JSON control endpoint (default port
9000). Every enabled protocol binds its own OS-assigned ephemeral
port; clients discover those ports — and verify wire-protocol
compatibility — by handshaking against the control port. The control
port is the only port you normally choose.
# Start server (control endpoint on 9000; every test listener ephemeral)
# Run a single-protocol client test (only --server + --control-port needed)
# WiFi latency-under-load stress test (UDP): idle baseline + latency under saturation
# Longer test, more connections, export to CBOR
# Run the full multi-protocol suite (drives every advertised protocol)
# Print a previously saved result
For more advanced usage, refer to help:
# Verbosity / color are global: -v (debug), -vv (trace), -q (quiet), --color never
# Shell completions and man pages:
Exporting Results
Add a -e or --export flag to client commands to save results.
The data format is CBOR — there is no JSON export. HTML is available
as a rendered single-file report for visual inspection.
# Export raw data (re-importable)
# Export rendered HTML report
# No extension implies CBOR
Other extensions (.json, .txt, …) are rejected with a clear error.
WiFi / Latency-Under-Load Stress Test
WiFi cards and the AP on the other end produce their worst latency under load —
airtime contention, driver/AP queue buildup (bufferbloat), power-save wakeups,
background scans and rate adaptation all show up as latency spikes that an idle
ping never sees. The latency-under-load test (UDP only) exposes them:
# Captures a short idle baseline, then probes latency at ~200 Hz while
# saturating the link in both directions.
# Aliases: --type wifi, --type latency-under-load
# Export an HTML report with the interactive-looking latency chart:
How to read the output:
- Latency over time — a time-vs-latency chart (Unicode sparkline in the terminal, an SVG in the HTML report) so spikes are visible at a glance. The HTML chart overlays the idle baseline against the under-load series.
- Spikes — a verdict (
Clean/Occasional/Frequent) from adaptive spike detection: any probe exceedingmax(median × 3, median + 20 ms)counts as a spike. Frequent or severe spikes point at a misbehaving card / AP. - Tail RTT (p95 / p99 / p99.9) — the tail is where WiFi latency hides; the median can look healthy while the tail tells the real story.
- Bufferbloat — the median and p99 latency inflation from idle to under load. A large jump is the classic bufferbloat signature.
Loopback (-s 127.0.0.1) is useful for a smoke test but won't show real spikes —
point it across the actual WiFi link to a server on the wired side to see them.
Use --target-rate-mbps <N> to probe latency under a fixed load instead of full
saturation.
Developer Notes
HTTP Test Endpoints
When running server with HTTP, the following endpoints are available:
GET /download?size=<total_size>&chunk_size=<chunk_size>- Download test dataPOST /upload- Upload test endpointGET /latency- Minimal latency testGET /info- Server informationGET /health- Server health check
UDP Test Implementation
The UDP test uses a small, iperf3-u-style "blaster" protocol: a fixed-rate sender, no retransmissions, server-side counting of received / lost / out-of-order packets and RFC 3550 interarrival jitter. Use --target-rate-mbps <N> to pace at a specific rate, or leave it at the default 0 to saturate. Pacing uses tokio::time::sleep and is therefore approximate above ~100 Mbps; for higher rates either accept the bursting or shape externally with tc fq. A QUIC-based congestion-controlled UDP mode is on the roadmap.
Future Improvements
There are several features/improvements that are planned.
- OCI Container images using all popular base images (necessary for representative performance testing)
- Kubernetes support (for server)
- QUIC support (HTTP/3 and raw QUIC streams)
- gRPC support?
- Rich HTML report generation
- Support for more niche protocols (e.g. SFTP, SMB)
- Remove SSH server spin-up (remote SSH server downloads binary, or through client, and runs server based on what's specified by client)
- Mobile app support (iOS/Android)
- Firm up IPV6 support (which has different NAT characteristics)
Development
This repo uses mise for tooling/tasks and hk for git hooks. See CONTRIBUTING.md for details.
&&
Contributing
Contributions are welcome! This tool aims to be the most comprehensive network testing suite available. Areas for improvement:
- Improve internal overhead of HTTP tests (e.g. to test against 25+ Gbps links)
- Additional protocol support (QUIC, HTTP/3, SFTP, SMB)
- More advanced topology analysis
- Real-time monitoring capabilities
- Web interface for results visualization
- Integration with network monitoring systems
License
This project is licensed under the Apache License 2.0.