# Iroh Relay Modes Explained: Disabled, Default, Staging, and Custom Configurations

> Explore Iroh's relay modes Disabled, Default, Staging, and Custom. Understand how these configurations manage node connections via relay servers when direct links fail.

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

---

**Iroh provides four distinct relay modes—`Disabled`, `Default`, `Staging`, and `Custom`—that control how nodes connect through relay servers when direct connections fail.**

The Iroh networking stack, maintained in the `n0-computer/iroh` repository, uses the `RelayMode` enum to determine whether and how endpoints utilize relay infrastructure for NAT traversal and fallback routing. These modes are defined in [[`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs)](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs) and allow developers to tune connectivity behavior from completely offline P2P setups to globally distributed production deployments.

## The Four Iroh Relay Modes

The `RelayMode` enum (lines 1912–1925 in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs)) specifies exactly how an endpoint resolves relay addresses. Each variant maps to a different relay infrastructure strategy.

### Disabled Mode

**`RelayMode::Disabled`** prevents the endpoint from adding any relay transport, forcing the node to attempt only direct IP connections.

This mode is optimal for peer-to-peer deployments on trusted LANs or air-gapped environments where relay traffic—typically tunneled over HTTPS—must be avoided entirely. When disabled, hole-punching through NATs relies solely on direct IP discovery without relay assistance.

### Default Mode

**`RelayMode::Default`** activates the production relay map that ships with Iroh, commonly referred to as the "number 0" relays.

This is the standard configuration for most applications, providing immediate access to a globally distributed set of relay servers maintained by the Iroh team. The default map requires no additional configuration and handles hole-punching and fallback routing automatically.

### Staging Mode

**`RelayMode::Staging`** directs the endpoint to use a separate staging relay fleet intended for testing and development.

This mode activates when explicitly configured or when the environment variable `IROH_FORCE_STAGING_RELAYS` is set. Staging relays allow integration testing against non-production infrastructure without polluting production relay metrics or capacity.

### Custom Mode

**`RelayMode::Custom(RelayMap)`** accepts a user-defined `RelayMap` containing specific `RelayUrl` entries.

This mode supports self-hosted relay infrastructure or curated subsets of public relays. The provided `RelayMap` must contain at least one valid relay URL, and Iroh will treat these entries identically to the built-in production map for hole-punching and routing decisions.

## Under the Hood: How Relay Modes Are Processed

Internally, the `RelayMode` implementation includes a helper method `relay_map()` starting at line 1934 in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs). This method converts the enum variant into a concrete `RelayMap` instance:

- `Disabled` returns an empty map
- `Default` and `Staging` resolve to their respective built-in configurations
- `Custom` returns the user-supplied map directly

The endpoint builder later transforms this map into a `TransportConfig::Relay` entry, inserting it into the transport list used during connection establishment.

## Configuring Iroh Relay Modes in Practice

To select a relay mode, use the `relay_mode()` builder method on the `Endpoint` before calling `bind()`. Below are complete examples for each configuration.

### Using Default Production Relays

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

let ep = Endpoint::builder(presets::N0)
    .relay_mode(RelayMode::Default)
    .bind()
    .await?;

```

### Disabling Relays for Direct-Only Connections

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

let ep = Endpoint::builder(presets::N0)
    .relay_mode(RelayMode::Disabled)
    .bind()
    .await?;

```

### Targeting Staging Infrastructure

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

let ep = Endpoint::builder(presets::N0)
    .relay_mode(RelayMode::Staging)
    .bind()
    .await?;

```

### Deploying Custom Relay Infrastructure

```rust
use iroh::{Endpoint, RelayMode, RelayMap, endpoint::presets};
use iroh_base::RelayUrl;

let my_map = RelayMap::from(vec![
    RelayUrl::from_str("https://my-relay.example.com")?,
    RelayUrl::from_str("https://another-relay.example.org")?,
]);

let ep = Endpoint::builder(presets::N0)
    .relay_mode(RelayMode::Custom(my_map))
    .bind()
    .await?;

```

## When to Use Each Iroh Relay Mode

Select your relay configuration based on deployment constraints and network topology:

- **Use `Disabled`** for LAN-only clusters, offline-first applications, or compliance environments forbidding external relay connections.
- **Use `Default`** for production workloads requiring global reachability without operational overhead of relay management.
- **Use `Staging`** when running CI/CD pipelines, pre-production validation, or when testing relay protocol changes.
- **Use `Custom`** when operating private infrastructure, complying with data residency requirements, or implementing relay topology optimizations.

## Summary

- Iroh relay modes are controlled by the `RelayMode` enum in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs), supporting four distinct variants.
- **`Disabled`** blocks all relay traffic, enforcing direct IP connections only.
- **`Default`** connects to the production "number 0" relay fleet for global hole-punching.
- **`Staging`** routes through test relays, activated via configuration or the `IROH_FORCE_STAGING_RELAYS` environment variable.
- **`Custom(RelayMap)`** allows self-hosted relay URLs, requiring at least one valid entry in the provided map.
- The `relay_map()` method at line 1934 converts enum variants into transport configurations that the endpoint builder applies during initialization.

## Frequently Asked Questions

### What is the difference between RelayMode::Default and RelayMode::Staging?

`RelayMode::Default` connects to the production relay infrastructure maintained by the Iroh team, providing global coverage for hole-punching. `RelayMode::Staging` connects to a separate test relay fleet used for development and CI/CD validation, preventing test traffic from affecting production capacity.

### Can I use multiple relay modes simultaneously in one application?

No, an Iroh `Endpoint` accepts exactly one `RelayMode` configuration during initialization. However, the `Custom` variant accepts a `RelayMap` containing multiple relay URLs, allowing you to specify redundant relay endpoints within a single mode configuration.

### What happens if I specify RelayMode::Custom with an empty relay map?

Iroh requires the `RelayMap` in `RelayMode::Custom` to contain at least one valid `RelayUrl`. Providing an empty map will result in a configuration error during endpoint initialization, as the transport layer requires at least one relay endpoint for the mode to function.

### Does RelayMode::Disabled affect direct connection attempts?

No, `RelayMode::Disabled` only removes relay transport from the endpoint's available strategies. Direct IP connections—including hole-punching attempts via other mechanisms—continue to function normally. This mode simply prevents the endpoint from using HTTPS-based relay servers as a fallback or discovery mechanism.