Enable the termination feature to allow the application to handle SIGTERM signals gracefully, ensuring proper cleanup during shutdown.
irtt-rs
irtt-rs is a Rust implementation of an IRTT-compatible client and server:
finite or continuous UDP latency probing, plus the server side those probes
run against.
This is not the upstream IRTT project. For the original implementation,
protocol background, and broader documentation, see
heistp/irtt. The installed dispatcher is
named irtt-rs rather than irtt to avoid conflicting with or being
mistaken for it.
Features
- Finite and continuous probe sessions
- Concurrent probing of multiple targets, with staggered or burst pacing
- Reusable client library with a structured event stream (blocking, Tokio, or managed)
- Human-readable table output, plus CSV, TSV, and JSON Lines for scripts and monitoring systems, with selectable output columns
- Optional terminal UI
- Reusable Tokio-native server library
- UDP server applet with sensible zero-argument defaults and explicit bind and session-policy options
- Router-friendly multi-applet binary layout
Comparison with upstream IRTT
irtt-rs is an independent, compatible reimplementation, not a successor or
replacement for upstream IRTT — heistp/irtt
remains the original implementation. Interoperability is a project goal; see
docs/INTEROP_COMPARISON.md and
docs/protocol/ for the black-box interoperability
methodology and protocol baseline this project verifies against. Choose
between them based on the capabilities and deployment model you need.
The table below was checked against upstream release v0.9.2 (2026-07-17). This project's own interop testing and protocol baseline are currently pinned to the prior release, v0.9.1; the wire protocol version number is unchanged between the two, but v0.9.2 has not itself been exercised against this project's interop harness.
| Capability | irtt-rs | upstream IRTT (v0.9.2) |
|---|---|---|
| Wire protocol | Protocol version 1, verified against upstream v0.9.1 | Protocol version 1 (unchanged in v0.9.2) |
| Finite probing | Supported, default 10s | Supported, default 1m |
| Continuous/indefinite operation | Supported (--duration 0); still computes running statistics (see below) |
Supported via streaming mode (-s, added in v0.9.2); computes no statistics at all in that mode |
| Statistics in continuous mode | Running count/min/max/mean/variance per target; exact medians unavailable; bounded IPDV tracking | None in streaming mode — raw/event output only, by design, to avoid unbounded memory |
| Multi-target probing (one invocation) | Supported, with labels and staggered/burst pacing | Not supported — one remote address per invocation |
| Terminal UI | irtt-tui, a live graph/dashboard applet |
Not present |
| Output formats | table, csv, tsv, jsonl, with selectable columns | Text summary, JSON (optionally gzip to file), and a fixed-field raw mode; no CSV/TSV and no column selection |
| Client/server library API | Separate, independently versioned Rust crates (irtt-client, irtt-server) |
One combined Go package exposing both roles |
| Server: multiple listeners | ServerSet supervises several listeners in one process |
ListenAndServe also serves multiple requested addresses |
| Server: wildcard reply-source | Default behavior on Linux/macOS/FreeBSD; refused elsewhere rather than served incorrectly | Opt-in via --set-src-ip, with a documented per-packet allocation cost |
| Server: zero-argument bind | Binds the wildcard address on both families by default, gated by the platform check above | Binds the wildcard address on both families by default; no documented platform gate |
| Prebuilt release binaries | Published for six target triples | None published; install via go install or manual build |
Upstream has capabilities this project does not implement: a report
subcommand for replaying saved JSON results, benchmarking and
timer/clock-diagnostic subcommands, client-side payload fill and
don't-fragment/wait-strategy/timer-algorithm controls, an operator-configurable
server-side fill policy (this project's server always honors a session's
negotiated fill request, with a fixed fallback pattern, but has no equivalent
to upstream's flags for restricting or overriding it), syslog logging, and
bundled systemd/OpenRC service files.
This project has capabilities upstream does not implement: multi-target probing with labels, the terminal UI, CSV/TSV output with selectable columns, a quantified and actively-warned memory-retention model for long-running client sessions, and best-effort Linux kernel-timestamp preference for its own send/receive endpoint.
Installation
The build requires Rust 1.88 or newer.
Install the latest release from crates.io:
cargo install irtt-rs --locked
This installs the irtt-rs dispatcher plus dedicated irtt-client,
irtt-tui, and irtt-server binaries. Each applet can also be built in
isolation with --no-default-features plus the applet's own feature, for
example a lightweight client-only install:
cargo install irtt-rs --locked --no-default-features --features client
For development, or to install directly from a checkout:
git clone https://github.com/Lochnair/irtt-rs.git
cd irtt-rs
cargo install --path crates/irtt-app --locked
Quick start
Probe a server:
irtt-client netperf-eu.bufferbloat.net:2112 --duration 30s --interval 100ms
Probe continuously until interrupted (Ctrl-C):
irtt-client netperf-eu.bufferbloat.net:2112 --duration 0
Watch the same session live in the terminal UI:
irtt-tui netperf-eu.bufferbloat.net:2112
Run a server with sensible defaults — no --bind needed:
irtt-server
Documentation
docs/irtt-client.md— target syntax, output formats and columns, measurement field definitions, finite/continuous memory behavior, kernel timestamps.docs/irtt-tui.md— controls, continuous default, retained history.docs/irtt-server.md— bind defaults and overrides, wildcard listener behavior, session policy, HMAC.docs/irtt-rs.md— the multicall dispatcher, applet binary names, feature-gated builds.- docs.rs for the library crates below.
docs/protocol/anddocs/INTEROP_COMPARISON.mdfor the wire protocol specification and interoperability validation against upstreamirtt.
Every applet also documents its full option list with --help.
Crates
| Crate | crates.io | What it is |
|---|---|---|
irtt-rs |
crates.io | Application package: the irtt-rs, irtt-client, irtt-tui, and irtt-server binaries |
irtt-client |
crates.io | Reusable client/session library (docs.rs) |
irtt-server |
crates.io | Reusable Tokio-native server library (docs.rs) |
irtt-stats |
crates.io | Statistics aggregation over irtt-client events (docs.rs) |
irtt-proto |
crates.io | Low-level wire protocol encode/decode (docs.rs) |
Each library crate has its own crates.io README describing what it's for and
when to use it instead of irtt-client/irtt-server directly.
Binaries and features
| Build | Binaries |
|---|---|
--no-default-features |
irtt-rs |
--no-default-features --features client |
irtt-rs, irtt-client |
--no-default-features --features server |
irtt-rs, irtt-server |
--no-default-features --features tui |
irtt-rs, irtt-tui |
Default features (or --all-features) |
irtt-rs, irtt-client, irtt-tui, irtt-server |
Development
cargo fmt --all -- --check
cargo test --workspace --locked
cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
See AGENTS.md for architecture, testing policy, and the
clean-room provenance boundary this project maintains against upstream
irtt.