# Performance Characteristics of iroh: How the Rust Library Achieves High-Throughput P2P Transfers

> Discover irohs performance characteristics for high-throughput P2P transfers. Explore its QUIC, async Tokio, zero-copy, and NAT traversal optimizations for gigabit speeds and low latency.

- Repository: [number zero/iroh](https://github.com/n0-computer/iroh)
- Tags: performance
- Published: 2026-06-21

---

**iroh delivers gigabit-class throughput and sub-10ms latency by combining QUIC-based multiplexed streams, async Tokio runtime tuning, zero-copy blob handling, and intelligent NAT traversal with relay fallback.**

iroh is a Rust library maintained by n0-computer that establishes peer-to-peer connections over QUIC. Understanding the performance characteristics of iroh helps developers optimize for workloads ranging from small control messages to multi-terabyte blob transfers. The library achieves its efficiency through a modular architecture that minimizes overhead while maximizing concurrency.

## Core Performance Architecture

The performance characteristics of iroh stem from three foundational components working in concert.

### QUIC-Based Transport with quinn

At the transport layer, iroh uses the `quinn` implementation of QUIC in [`iroh/src/transport/quic.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/transport/quic.rs). QUIC provides native multiplexed streams, built-in congestion control, and TLS encryption without head-of-line blocking. This allows iroh to saturate network links with many concurrent streams over a single connection.

### NAT Traversal and Relay Fallback

The `Endpoint` implementation in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs) attempts hole-punching for direct paths first. When NAT traversal succeeds, latency drops to sub-10ms ranges on local networks. If direct connection fails, the library falls back to encrypted relays, preserving end-to-end encryption while maintaining measurable throughput.

### Async Tokio Runtime Tuning

Each endpoint runs on a dedicated Tokio runtime. The `--workers-per-ep` parameter controls thread allocation. Benchmarks in [`iroh/bench/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/bench/src/lib.rs) demonstrate that two workers per endpoint provide optimal balance between ACK processing and data transmission, allowing the library to scale across CPU cores efficiently.

## Benchmarking iroh Performance

The repository includes `iroh-bench`, a dedicated benchmarking tool located in [`iroh/bench/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/bench/src/lib.rs), that drives the library under configurable loads.

### Configurable Load Parameters

The benchmark tool accepts several CLI parameters to simulate different network conditions:

- `--clients`: Number of simultaneous endpoints
- `--streams`: Concurrent streams per client
- `--max-streams`: Upper bound for simultaneous streams
- `--download-size` and `--upload-size`: Payload sizes with SI prefixes
- `--workers-per-ep`: Tokio worker threads per endpoint

### Metrics Collection in stats.rs

The [`iroh/bench/src/stats.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/bench/src/stats.rs) file defines `Stats` and `StreamStats` structures that collect per-stream histograms. Key metrics include:

- **Time to First Byte (TTFB)**: Captured in `TransferResult::new` at lines 19-20
- **Throughput**: Calculated as `size / duration` in `throughput_bps` at lines 33-34
- **Chunk timing**: Per-chunk latency and size distributions

Sample output shows detailed percentiles:

```

Overall upload stats:
Transferred 4.09 GiB on 8 streams in 5.12 s (0.80 MiB/s)
Time to first byte (TTFB): 12.4 ms
Total chunks: 12345
Average chunk time: 0.41 ms

```

## Memory and CPU Efficiency

iroh minimizes resource overhead through zero-copy operations and protocol layering.

### Zero-Copy Blob Handling via iroh-blobs

The `iroh-blobs` crate implements BLAKE3-based content addressing. Data transfers stream without copying between buffers, reducing CPU overhead and memory pressure during large file transfers. This is critical for multi-terabyte workloads.

### Multi-Protocol Composition

Protocol handlers for gossip and blobs layer atop the same QUIC connection. This avoids the cost of establishing separate connections, keeping per-connection overhead low while maintaining isolation between protocol concerns.

## Code Examples

### Running Benchmarks Programmatically

You can embed the benchmark logic directly in Rust applications using the `iroh::bench` module:

```rust
use iroh::bench::{self, Opt};
use clap::Parser;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Configure: 4 clients, 4 streams each, 100 MiB download
    let opt = Opt {
        clients: 4,
        streams: 4,
        max_streams: 4,
        download_size: 100 << 20, // 100 MiB
        upload_size: 0,
        ..Default::default()
    };
    
    // Execute benchmark (same logic as iroh-bench CLI)
    bench::iroh::run(opt).await?;
    Ok(())
}

```

### Accessing Transfer Statistics

Extract detailed metrics from completed transfers using the stats structures:

```rust
use iroh::bench::stats::{Stats, StreamStats};

fn report(stats: &Stats) {
    println!("Total bytes: {}", stats.total_size);
    
    let throughput_mib = stats.stream_stats.throughput_hist.mean() as f64 
        / 1024.0 / 1024.0;
    println!("Average throughput: {:.2} MiB/s", throughput_mib);
    
    let ttfb_ms = stats.stream_stats.ttfb_hist.mean() / 1_000.0;
    println!("Mean TTFB: {:.2} ms", ttfb_ms);
}

```

## Summary

- **QUIC multiplexing** enables high concurrency without head-of-line blocking, allowing full link saturation.
- **Tokio runtime tuning** via `--workers-per-ep` provides scalable CPU utilization, with two workers per endpoint recommended for optimal ACK processing.
- **Zero-copy blob handling** using BLAKE3 content addressing minimizes memory overhead for large transfers.
- **Intelligent path selection** prioritizes direct hole-punched connections for sub-10ms latency, falling back to encrypted relays only when necessary.
- **Built-in benchmarking** in [`iroh/bench/src/stats.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/bench/src/stats.rs) provides granular visibility into TTFB, throughput percentiles, and chunk-level timing.

## Frequently Asked Questions

### What throughput can iroh achieve on standard hardware?

According to benchmarks in [`iroh/bench/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/bench/src/lib.rs), iroh achieves gigabit-class throughput on commodity hardware when properly configured with `--workers-per-ep 2`. The QUIC transport allows multiple streams to saturate the network link without throttling each other.

### How does iroh minimize latency for peer-to-peer connections?

The library prioritizes direct hole-punched connections established through the `Endpoint` in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs). When direct paths succeed, Time to First Byte (TTFB) drops to sub-10ms ranges on local networks. The relay fallback adds minimal overhead while preserving end-to-end encryption.

### What is the optimal configuration for benchmarking iroh performance?

Based on the implementation in [`iroh/bench/src/stats.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/bench/src/stats.rs), configure `--workers-per-ep 2` to balance ACK processing and data transmission. Set `--clients` and `--streams` to match your expected concurrency level, and use `--download-size` with SI prefixes (e.g., `100MiB`) to specify realistic payloads.

### How does iroh handle memory pressure during large file transfers?

The `iroh-blobs` crate implements zero-copy streaming using BLAKE3 content addressing. This eliminates buffer copies between the transport layer and application code, keeping memory usage constant regardless of file size.