# iroh RelayMode: Default, Staging, and Disabled Explained

> Understand iroh RelayMode Default staging and disabled. Learn how each setting affects your endpoint's use of public production or testing relays for direct-only connections.

- Repository: [number zero/iroh](https://github.com/n0-computer/iroh)
- Tags: deep-dive
- Published: 2026-07-14

---

**iroh's `RelayMode` enum determines whether your endpoint uses public production relays, staging relays for testing, or disables relay entirely for direct-only connections.**

The `RelayMode` configuration controls how iroh endpoints establish connectivity across NATs and firewalls. Defined in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs), this enum selects which relay servers facilitate hole-punching and packet forwarding when direct peer-to-peer connections fail. Understanding the differences between `Default`, `Staging`, and `Disabled` ensures you choose the right relay strategy for your deployment environment.

## What is iroh RelayMode?

`RelayMode` is an enum defined at lines 1922–1943 in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs) that specifies how an iroh `Endpoint` should handle relay services. Relays act as intermediary servers that help establish direct connections between peers behind restrictive network configurations. When direct connections fail, traffic flows through these HTTPS relays temporarily until a direct path is established.

The mode you select determines which relay servers the endpoint contacts at startup:

- **Production fleet** for stable end-user applications
- **Staging fleet** for testing bleeding-edge relay software
- **No relays** for LAN-only or security-restricted scenarios

## The Three Built-in RelayMode Variants

### Default (Production)

`RelayMode::Default` selects the **production relay map**, which resolves to `crate::defaults::prod::default_relay_map()` in [`iroh/src/defaults.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/defaults.rs). This configuration uses the publicly-hosted, stable relay infrastructure shipped with iroh.

Use this variant for production deployments and end-user applications where stability is prioritized. This is the standard configuration unless overridden by the `IROH_FORCE_STAGING_RELAYS` environment variable (handled at lines 1976–1982 in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs)).

### Staging

`RelayMode::Staging` switches to the **staging relay map**, resolving to `crate::defaults::staging::default_relay_map()`. This connects your endpoint to a separate fleet of relay servers running newer software versions before they reach production.

Select this mode for CI pipelines, temporary testing environments, or when experimenting with new relay implementations. The staging fleet allows you to validate compatibility without affecting production traffic.

### Disabled

`RelayMode::Disabled` **eliminates all relay functionality**. The `From<RelayMode>` implementation returns `None` for the transport configuration, preventing the endpoint from performing hole-punching or forwarding traffic over HTTPS. The endpoint attempts only direct connections.

Choose this variant when both peers reside on the same LAN where NAT traversal is unnecessary, or when enforcing strict "no-relay" policies for security compliance or cost reduction.

## How RelayMode Works Under the Hood

The enum conversion logic in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs) maps these variants to concrete relay configurations:

```rust
// Lines 1922-1943 in iroh/src/endpoint.rs
pub enum RelayMode {
    Default,
    Staging,
    Disabled,
    Custom(RelayMap),
}

```

When constructing an `Endpoint`, the builder's `relay_mode()` method accepts this enum. For `Default` and `Staging`, the implementation fetches the corresponding static relay maps from [`iroh/src/defaults.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/defaults.rs). For `Disabled`, the conversion yields `None`, signaling the transport layer to skip relay initialization entirely.

## Practical Examples

Configure your endpoint's relay behavior using the builder pattern:

```rust
use iroh::{Endpoint, RelayMode, presets};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Production relay (default behavior)
    let ep_default = Endpoint::bind(presets::N0).await?
        .relay_mode(RelayMode::Default);
    
    // Staging relay for testing
    let ep_staging = Endpoint::bind(presets::N0).await?
        .relay_mode(RelayMode::Staging);
    
    // Direct connections only
    let ep_disabled = Endpoint::bind(presets::N0).await?
        .relay_mode(RelayMode::Disabled);
    
    // Custom relay infrastructure
    use iroh::relay_url::RelayUrl;
    use iroh::relay_map::RelayMap;
    use std::str::FromStr;
    
    let my_relays = RelayMap::from_iter([
        RelayUrl::from_str("https://my-relay.example.com/")?,
    ]);
    
    let ep_custom = Endpoint::bind(presets::N0).await?
        .relay_mode(RelayMode::Custom(my_relays));
    
    Ok(())
}

```

## When to Use Each Mode

Select your relay configuration based on these specific scenarios:

- **`RelayMode::Default`** – Production applications, stable releases, and general-purpose peer-to-peer networking where reliable connectivity across the public internet is required.
- **`RelayMode::Staging`** – Pre-production testing, relay software validation, and development environments where you need to verify compatibility with upcoming relay server changes.
- **`RelayMode::Disabled`** – LAN-only deployments, high-security environments that forbid relay servers, or specialized topologies where you manage your own direct connection establishment.

## Summary

- **`RelayMode::Default`** uses the production relay fleet via `default_relay_map()` for stable, public internet connectivity.
- **`RelayMode::Staging`** connects to the staging fleet for testing new relay software before production deployment.
- **`RelayMode::Disabled`** removes relay functionality entirely, allowing only direct connections and skipping NAT hole-punching.
- The enum is defined in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs) with conversion logic that maps variants to concrete relay configurations sourced from [`iroh/src/defaults.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/defaults.rs).

## Frequently Asked Questions

### What's the difference between Default and Staging relay modes in iroh?

`RelayMode::Default` connects to the stable production relay infrastructure maintained by the iroh team, while `RelayMode::Staging` points to a separate fleet running newer, potentially unstable software intended for testing. The staging environment allows developers to validate relay protocol changes without risking production traffic.

### When should I disable relays in iroh?

Disable relays using `RelayMode::Disabled` when operating endpoints within the same local network where NAT traversal is unnecessary, or when organizational security policies forbid third-party relay servers. This configuration eliminates HTTPS relay traffic but prevents connectivity between peers behind strict firewalls that require hole-punching assistance.

### Can I use custom relay servers instead of the built-in maps?

Yes. `RelayMode::Custom(RelayMap)` accepts your own `RelayMap` instance containing specific `RelayUrl` endpoints. This variant is defined alongside the standard modes in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs) and enables private relay infrastructure or geographically-specific relay selection.

### How does iroh handle relay selection at runtime?

The `Endpoint` builder evaluates `RelayMode` during initialization, converting the enum variant to a specific relay configuration via the `From` implementation. For `Default` and `Staging`, this loads static URL lists from [`iroh/src/defaults.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/defaults.rs). You can override the default selection by setting the `IROH_FORCE_STAGING_RELAYS` environment variable, which forces `RelayMode::Staging` behavior regardless of code configuration.