RelayMode Default vs Disabled vs Custom in iroh: Endpoint Connection Modes Explained
RelayMode::Default uses iroh's built-in production relays for NAT traversal, RelayMode::Disabled (sometimes referred to as "NoRelay") blocks all relay traffic to enforce direct peer-to-peer connections only, and RelayMode::Custom accepts an explicit RelayMap for private relay infrastructure.
The RelayMode enum in the n0-computer/iroh repository controls how an Endpoint discovers and utilizes relay servers during connection establishment. Defined in [iroh/src/endpoint.rs](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs), this configuration determines whether your application relies on public relay servers, operates without relay assistance, or connects to specific self-hosted relays.
RelayMode::Default: Production Relay Infrastructure
RelayMode::Default configures the endpoint to use the production relay map embedded in the library. According to the source code at line 1929, this variant invokes crate::defaults::prod::default_relay_map() to retrieve the list of public relays operated by the iroh team.
Use this mode for general internet-facing applications where you require reliable, globally-available relays without manual configuration. When direct hole-punching fails due to restrictive NATs or firewalls, the endpoint automatically falls back to these production relays to maintain connectivity.
RelayMode::Disabled: Direct-Only Communication
RelayMode::Disabled disables all relay functionality entirely. As implemented in the source branch at lines 1929-1930, the endpoint will never attempt to hole-punch or forward traffic through relay servers. All connection attempts must succeed via direct peer-to-peer paths or fail immediately.
Select this mode when operating in trusted, fully reachable networks such as internal LANs or VPNs where you want to eliminate relay traffic entirely. This configuration is also available via the presets module in [iroh/src/endpoint/presets.rs](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint/presets.rs) for quick "no relay" endpoint setup.
RelayMode::Custom: Private Relay Deployments
RelayMode::Custom(RelayMap) accepts an explicit relay map containing your own relay URLs. The variant definition at lines 1922-1924 wraps a user-provided RelayMap, and the helper constructor RelayMode::custom() (lines 51-53) simplifies construction from any iterator of URLs.
This mode is essential for private deployments, corporate environments with specific firewall requirements, or edge-located relays. Unlike Default, which pulls from iroh/defaults/prod, Custom uses exactly the relays you specify via the RelayUrl type defined in [iroh-base/src/relay_url.rs](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/relay_url.rs).
Key Differences in Network Behavior
The three modes differ fundamentally in their source of relay URLs and fallback behavior:
- Source of URLs –
Defaultpulls the built-in production list;Customuses your provided list;Disableduses none. - Connection Resilience – With
DefaultorCustom, the endpoint can fall back to relays when direct paths fail. WithDisabled, connection failures are terminal. - Configuration Complexity –
Defaultrequires no additional code;Customrequires building aRelayMap;Disabledis a single variant value.
Configuring Your Endpoint: Code Examples
The following patterns from [iroh/examples/listen.rs](https://github.com/n0-computer/iroh/blob/main/iroh/examples/listen.rs#L31) demonstrate practical usage of each relay mode:
use iroh::{Endpoint, RelayMode};
fn main() -> anyhow::Result<()> {
// Default: Use production relays shipped with iroh
let endpoint_default = Endpoint::builder()
.relay_mode(RelayMode::Default)
.bind()?;
// Disabled (No Relay): Direct connections only
let endpoint_disabled = Endpoint::builder()
.relay_mode(RelayMode::Disabled)
.bind()?;
// Custom: Specific private relay servers
let custom_map = iroh::RelayMap::from_iter([
"https://relay1.example.com/".parse()?,
"https://relay2.example.com/".parse()?,
]);
let endpoint_custom = Endpoint::builder()
.relay_mode(RelayMode::Custom(custom_map))
.bind()?;
Ok(())
}
For convenience, the RelayMode::custom() helper (lowercase) automatically wraps your URLs into a RelayMap, while the RelayMode::Custom variant (uppercase) accepts a pre-constructed map directly.
Summary
RelayMode::Defaultleverages the built-in production relay map (defaults::prod) for automatic NAT traversal without configuration.RelayMode::Disabledeliminates all relay functionality, requiring successful direct peer-to-peer paths or failing the connection.RelayMode::Customrequires a manually constructedRelayMapfor complete control over relay server selection in private networks.
Frequently Asked Questions
What is the difference between RelayMode::Disabled and NoRelay?
RelayMode::Disabled is the actual enum variant name in [iroh/src/endpoint.rs](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs), while "NoRelay" is the conceptual description used in documentation and the presets module. Both refer to the same behavior: completely disabling relay assistance and forcing direct connections only.
When should I use RelayMode::Custom instead of Default?
Use RelayMode::Custom when operating in restricted network environments, testing self-hosted relay infrastructure, or deploying within corporate networks that block external relay endpoints. RelayMode::Default is preferable for general applications requiring the global availability of iroh's public relay fleet without configuration overhead.
How does RelayMode affect connection establishment?
RelayMode::Disabled attempts only direct connections, failing fast when peers are unreachable. RelayMode::Default and RelayMode::Custom may increase initial connection latency while attempting UDP hole-punching, but ultimately succeed by falling back to relay servers when direct paths fail.
Can I change RelayMode on an existing Endpoint?
No. The RelayMode is fixed during Endpoint construction via the builder pattern and cannot be modified dynamically. To alter relay behavior, you must create a new Endpoint instance with the desired configuration using Endpoint::builder().
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 →