Iroh Node Performance Benchmarks: Complete Guide to QUIC Throughput and Latency Testing

Iroh provides a dedicated iroh-bench crate that measures QUIC connection latency, bidirectional throughput, stream multiplexing efficiency, and relay performance through configurable command-line benchmarks.

The n0-computer/iroh repository ships with a comprehensive benchmarking suite designed to exercise core networking libraries including the noq QUIC implementation, relay client, and transport layers. These benchmarks allow developers to quantify node performance across real-world network conditions, from direct peer-to-peer connections to relay-mediated scenarios. The suite integrates directly into CI pipelines to catch performance regressions before they reach production.

Benchmark Architecture and Core Metrics

The benchmarking framework resides in the iroh/bench crate and implements six primary performance dimensions. Each metric maps to specific source files and measurement strategies within the codebase.

Connection Latency Measurement

Connection latency tracks the time required to establish a QUIC handshake, including 0-RTT scenarios when available. In iroh/bench/src/iroh.rs, the run_client function instantiates an endpoint and records the duration of endpoint.connect calls. The benchmark captures the full handshake duration from Endpoint::bind() through successful connection establishment, providing millisecond-precision timing data for connection-oriented performance analysis.

Throughput and Transfer Statistics

Throughput benchmarks measure bytes-per-second performance on bidirectional streams. The TransferResult struct in iroh/bench/src/stats.rs aggregates bytes_sent and elapsed duration to compute megabits-per-second (Mbps) metrics. During execution, the benchmark opens bidirectional streams via conn.open_bi().await and repeatedly writes known-size payloads while the stats module collects timing data. This approach yields accurate bandwidth measurements that account for both transmission overhead and application-layer processing.

Stream Multiplexing Efficiency

To evaluate concurrent stream handling, the benchmark spawns multiple simultaneous streams within a single connection. The bulk benchmark implementation in iroh/bench/src/iroh.rs uses client_benchmark to generate concurrent load, measuring how many streams the endpoint can sustain without contention. This metric directly impacts real-world applications that need to transfer multiple data chunks simultaneously over a single QUIC connection.

Relay Performance Testing

When the --with-relay flag is enabled, the benchmark suite spins up a local iroh-relay instance and routes connections through it. As implemented in iroh/bench/src/lib.rs, this mode measures round-trip latency and bandwidth degradation introduced by relay indirection. The same statistical gathering applies, allowing direct comparison between direct peer connections and relay-mediated pathways.

Running the Benchmark Suite

The iroh-bench crate provides multiple execution modes through cargo commands, ranging from simple latency tests to high-concurrency stress scenarios.

Basic Client-Server Benchmarks

Run a standard performance test against a local endpoint with library metrics enabled:

cargo run -p iroh-bench -- \
    --addr 127.0.0.1:4433 \
    --duration 30s \
    --metrics

This command executes the default benchmark defined in iroh/bench/src/lib.rs, parsing CLI arguments and orchestrating the client-server interaction. The --metrics flag exposes internal iroh-net counters including packets sent, packets received, and retransmission counts.

Stress Testing with Bulk Operations

For high-load scenarios, use the bulk binary located at iroh/bench/src/bin/bulk.rs to spawn multiple concurrent clients:

cargo run -p iroh-bench --bin bulk -- \
    --clients 8 \
    --payload-size 4MiB \
    --duration 60s

The bulk benchmark stress-tests node capacity by running multiple simultaneous connections, each opening bidirectional streams and transferring large payloads. This reveals performance characteristics under contention that single-connection tests might mask.

Configuration Options and Worker Scaling

The benchmark suite supports granular runtime configuration through command-line flags defined in iroh/bench/src/lib.rs:

  • --workers-per-endpoint: Controls Tokio runtime worker thread allocation per endpoint, enabling scalability testing across different CPU core configurations
  • --with-relay: Enables relay-mediated connectivity testing
  • --metrics: Prints internal library counters via IrohNet::counters()

Test relay performance with increased worker threads:

cargo run -p iroh-bench -- \
    --addr 127.0.0.1:4433 \
    --with-relay \
    --metrics \
    --workers-per-endpoint 4

The CLI parses workers_per_endpoint and creates the specified number of Tokio runtime workers for each endpoint, allowing assessment of how thread pool sizing affects throughput and latency. This configuration mirrors production deployment scenarios where runtime resource allocation directly impacts node performance.

Summary

  • The iroh-bench crate provides comprehensive performance testing for QUIC connections, throughput, and relay scenarios
  • Core measurement logic resides in iroh/bench/src/iroh.rs for connection handling and iroh/bench/src/stats.rs for metric computation
  • Use --with-relay to quantify relay-induced latency versus direct connections
  • The --workers-per-endpoint flag enables thread-scaling analysis for production capacity planning
  • CI integration in .github/workflows/tests.yaml ensures performance regressions are caught automatically

Frequently Asked Questions

How does iroh measure connection latency in benchmarks?

The benchmark records the duration of endpoint.connect(addr, ALPN).await calls in iroh/bench/src/iroh.rs within the run_client function. This captures the full QUIC handshake time including TLS negotiation and 0-RTT resumption when applicable.

What throughput metrics does iroh-bench report?

The suite calculates megabits-per-second (Mbps) through the TransferResult struct in iroh/bench/src/stats.rs, which tracks bytes_sent and elapsed time during bidirectional stream operations. The metric accounts for payload transmission plus protocol overhead.

Can I benchmark iroh node performance with a relay server?

Yes. Pass the --with-relay flag to spin up a local relay instance and route traffic through it. This measures round-trip latency and bandwidth when direct peer-to-peer connectivity is unavailable, as implemented in the CLI parsing logic of iroh/bench/src/lib.rs.

How do I test concurrent stream performance?

Use the bulk binary (iroh/bench/src/bin/bulk.rs) with the --clients flag to spawn multiple simultaneous connections. Each client opens bidirectional streams via conn.open_bi(), allowing you to measure how the endpoint handles concurrent load and identify multiplexing bottlenecks.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →