Iroh Relay Modes Explained: Disabled, Default, Staging, and Custom Configurations
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) 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) 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. This method converts the enum variant into a concrete RelayMap instance:
Disabledreturns an empty mapDefaultandStagingresolve to their respective built-in configurationsCustomreturns 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
use iroh::{Endpoint, RelayMode, endpoint::presets};
let ep = Endpoint::builder(presets::N0)
.relay_mode(RelayMode::Default)
.bind()
.await?;
Disabling Relays for Direct-Only Connections
use iroh::{Endpoint, RelayMode, endpoint::presets};
let ep = Endpoint::builder(presets::N0)
.relay_mode(RelayMode::Disabled)
.bind()
.await?;
Targeting Staging Infrastructure
use iroh::{Endpoint, RelayMode, endpoint::presets};
let ep = Endpoint::builder(presets::N0)
.relay_mode(RelayMode::Staging)
.bind()
.await?;
Deploying Custom Relay Infrastructure
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
Disabledfor LAN-only clusters, offline-first applications, or compliance environments forbidding external relay connections. - Use
Defaultfor production workloads requiring global reachability without operational overhead of relay management. - Use
Stagingwhen running CI/CD pipelines, pre-production validation, or when testing relay protocol changes. - Use
Customwhen operating private infrastructure, complying with data residency requirements, or implementing relay topology optimizations.
Summary
- Iroh relay modes are controlled by the
RelayModeenum iniroh/src/endpoint.rs, supporting four distinct variants. Disabledblocks all relay traffic, enforcing direct IP connections only.Defaultconnects to the production "number 0" relay fleet for global hole-punching.Stagingroutes through test relays, activated via configuration or theIROH_FORCE_STAGING_RELAYSenvironment 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.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →