# How to Use Iroh's Default Relay Servers Provided by n0

> Easily use Iroh's default relay servers. Configure your client with RelayMode::Default to connect to n0's production infrastructure automatically. Get started now!

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

---

**To use Iroh's default relay servers, configure your `Endpoint` with `RelayMode::Default` in the builder, which automatically selects the production relay infrastructure operated by n0 without additional configuration.**

Iroh is a peer-to-peer networking library that establishes direct QUIC connections between peers, falling back to relay servers when NAT traversal fails. When you use **Iroh's default relay servers**, you leverage the production infrastructure maintained by n0 to ensure connectivity between peers behind firewalls or restrictive networks. This guide explains exactly how to configure these defaults based on the implementation in the n0-computer/iroh repository.

## What Are Relay Servers in Iroh?

Relay servers act as fallback intermediaries when direct UDP communication fails. When two peers cannot establish a direct connection due to NATs or firewalls, Iroh transparently routes traffic through these relays to maintain connectivity.

According to the iroh source code, the relay system is designed to be transparent to application code. You configure the relay mode during `Endpoint` initialization, and the library handles the complexity of hole-punching and fallback routing automatically.

## How Default Relays Are Configured

### The RelayMode Enum

The `RelayMode` enum in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs) (lines 1924-1926) defines how an endpoint selects its relay infrastructure:

```rust
pub enum RelayMode {
    Default,
    Custom(RelayMap),
    Disabled,
}

```

When you select `RelayMode::Default`, the endpoint automatically uses the production relay map. This is the recommended configuration for most applications using n0's infrastructure.

### Production Relay Map Definition

The actual production relays are defined in [`iroh/src/defaults.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/defaults.rs). The `default_relay_map()` function (lines 36-43) constructs a `RelayMap` containing four regional relay servers:

- **NA-East**: `use1-1.relay.n0.iroh.link.`
- **NA-West**: `usw1-1.relay.n0.iroh.link.`
- **EU**: `euc1-1.relay.n0.iroh.link.`
- **AP**: `aps1-1.relay.n0.iroh.link.`

Note that these hostnames end with a trailing dot to force DNS absolute resolution, as defined by the constants `NA_EAST_RELAY_HOSTNAME`, `NA_WEST_RELAY_HOSTNAME`, `EU_RELAY_HOSTNAME`, and `AP_RELAY_HOSTNAME` in [`iroh/src/defaults.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/defaults.rs) (lines 31-34).

The `RelayUrl` type in [`iroh-base/src/relay_url.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/relay_url.rs) provides a thin, cheaply clonable wrapper around `url::Url` that is used throughout the relay configuration system.

## Implementing Default Relays in Code

### Server Configuration Example

To configure a server endpoint that uses Iroh's default relay servers, instantiate the builder with `RelayMode::Default`. This pattern follows the implementation in [`iroh/examples/listen.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/examples/listen.rs):

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

#[tokio::main]
async fn main() -> Result<()> {
    // Generate a key pair for this endpoint
    let secret_key = SecretKey::generate();

    // Build the endpoint with default relay servers
    let endpoint = Endpoint::builder(presets::N0)
        .secret_key(secret_key)
        .alpns(vec![b"my/app".to_vec()])
        .relay_mode(RelayMode::Default)   // Uses n0's production relays
        .bind()
        .await?;

    // Wait until registered with a relay
    endpoint.online().await;

    println!("Listening on {:?}", endpoint.addr());

    // Accept incoming connections
    while let Some(incoming) = endpoint.accept().await {
        let conn = incoming.accept()?;
        println!("Incoming connection from {}", conn.remote_id());
    }

    Ok(())
}

```

### Client Configuration Example

Clients connecting to peers use the same configuration. The default relay map ensures both endpoints can discover each other even when behind NAT. This mirrors the pattern in [`iroh/examples/connect.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/examples/connect.rs):

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

#[tokio::main]
async fn main() -> Result<()> {
    let secret_key = SecretKey::generate();

    let endpoint = Endpoint::builder(presets::N0)
        .secret_key(secret_key)
        .alpns(vec![b"my/app".to_vec()])
        .relay_mode(RelayMode::Default)   // Same default map as the listener
        .bind()
        .await?;

    // Replace with actual EndpointId and addresses
    let remote_id = "...".parse()?;
    let remote_addrs = vec!["127.0.0.1:5000".parse()?];

    // The library will use default relays if direct UDP fails
    let conn = endpoint
        .connect(remote_id, remote_addrs, b"my/app")
        .await?;

    println!("Connected to {}", conn.remote_id());
    Ok(())
}

```

## Customizing Relay Configuration

### Using Staging Relays

For testing purposes, you can force the use of staging relays instead of production by setting the environment variable before starting your application:

```bash
export IROH_FORCE_STAGING_RELAYS=1

```

When this variable is set to any non-empty value, the library calls `crate::defaults::staging::default_relay_map()` instead of the production map. This logic is defined in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs) (lines 64-66).

### Creating Custom Relay Maps

If you need to pin specific relays or use your own infrastructure, construct a custom map using `RelayMode::custom`:

```rust
use iroh::{RelayMode, RelayUrl};

let custom = RelayMode::custom([
    "https://use1-1.relay.n0.iroh.link.".parse::<RelayUrl>()?,
    "https://euc1-1.relay.n0.iroh.link.".parse::<RelayUrl>()?,
]);

// Use in the endpoint builder
let endpoint = Endpoint::builder(presets::N0)
    .relay_mode(custom)
    .bind()
    .await?;

```

The `RelayMode::custom` implementation is found in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs) (lines 45-61).

## Summary

- **Iroh's default relay servers** are automatically selected when you configure `Endpoint::builder()` with `RelayMode::Default`.
- The production relay map contains four regional servers (NA-East, NA-West, EU, AP) defined in [`iroh/src/defaults.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/defaults.rs).
- The `RelayUrl` type in [`iroh-base/src/relay_url.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/relay_url.rs) provides efficient URL handling for relay configurations.
- Set `IROH_FORCE_STAGING_RELAYS=1` to use staging relays for testing.
- Use `RelayMode::custom()` to specify specific relay URLs when the defaults are not appropriate.

## Frequently Asked Questions

### What happens when I use RelayMode::Default?

When you select `RelayMode::Default`, the endpoint internally calls `default_relay_map()` from the defaults module, which returns a `RelayMap` containing the four production relay URLs operated by n0. The endpoint registers itself with these relays during the `bind()` operation, enabling fallback connectivity when direct UDP paths fail.

### Can I use custom relay servers instead of the defaults?

Yes, you can use `RelayMode::custom()` to provide a specific `RelayMap` containing your own relay URLs. This is useful for private deployments or when you need to restrict connectivity to specific geographic regions. Pass your custom map to `.relay_mode()` in the endpoint builder.

### How do I switch to staging relays for testing?

Set the environment variable `IROH_FORCE_STAGING_RELAYS` to any non-empty value before starting your application. This forces the use of `crate::defaults::staging::default_relay_map()` instead of the production map, allowing you to test against n0's staging infrastructure without modifying code.

### Are the default relay servers free to use?

The default relay servers operated by n0 are generally available for use with Iroh applications, but you should review n0's current terms of service and any applicable rate limits or fair use policies for production deployments. For high-volume applications, consider running your own relay infrastructure using `RelayMode::custom()`.