Skip to main content

Overview

The Fluxer Relay Directory is a service for discovering and managing voice relay servers. It provides a centralized registry of available relay servers with geographic information, capacity metrics, and health monitoring.

Endpoints

Browse relay directory endpoints

Relay Registration

Register new relay servers

Health Monitoring

Automatic health checks and failover

Geographic Routing

Location-based relay selection

What is a Relay?

A relay server is a WebRTC voice server that routes voice traffic between clients. The Relay Directory helps clients discover the best relay server based on:
  • Geographic proximity - Lower latency for users
  • Server capacity - Available connection slots
  • Health status - Active and responding servers only
  • Regional distribution - Global coverage

Architecture

Key Components

SQLite-based registry storing relay information:
  • Relay ID and name
  • URL and region
  • Geographic coordinates (latitude/longitude)
  • Capacity and current connections
  • Health status and last seen timestamp
  • Public key for encryption
Background service that periodically checks relay health:
  • HTTP health check requests
  • Marks relays as unhealthy after failed checks
  • Removes relays after extended downtime
  • Configurable check interval and failure threshold
Distance-based relay selection:
  • Haversine formula for distance calculation
  • Sorts relays by proximity to client
  • Filters unhealthy relays
  • Returns top N closest relays
Pre-configured relays loaded at startup:
  • Ensures service availability
  • Regional coverage
  • High-capacity servers

Base URL

The relay directory is typically deployed as a standalone service:
https://relay-directory.fluxer.app
For self-hosted instances, configure the relay directory URL in your deployment.

Authentication

The Relay Directory has two types of endpoints:

Public Endpoints

Public endpoints (listing, status) require no authentication:
GET /v1/relays
GET /v1/relays/:id/status

Administrative Endpoints

Relay management endpoints (register, heartbeat, delete) are currently unauthenticated but should be protected by network policies in production:
POST /v1/relays/register
POST /v1/relays/:id/heartbeat
DELETE /v1/relays/:id
In production deployments, relay management endpoints should be restricted to internal network access only or protected with API keys.

Configuration

The relay directory is configured via:
config: {
  server: {
    host: string,      // Listen host (default: 0.0.0.0)
    port: number,      // Listen port (default: 8090)
  },
  database: {
    path: string,      // SQLite database path
  },
  health_check: {
    enabled: boolean,           // Enable health checks
    interval_ms: number,        // Check interval (default: 30000)
    timeout_ms: number,         // Request timeout (default: 5000)
    failure_threshold: number,  // Failed checks before unhealthy (default: 3)
    removal_threshold: number,  // Failed checks before removal (default: 10)
  },
  bootstrap_relays: Array<{    // Pre-configured relays
    id: string,
    url: string,
    lat: number,
    lon: number,
    region: string,
    capacity: number,
    public_key?: string,
  }>,
}

Relay Information

Each relay in the directory contains:
interface RelayInfo {
  id: string;                    // Unique relay identifier
  name: string;                  // Human-readable name
  url: string;                   // WebSocket URL (wss://...)
  latitude: number;              // Geographic latitude
  longitude: number;             // Geographic longitude
  region: string;                // Region code (e.g., 'us-east', 'eu-west')
  capacity: number;              // Max concurrent connections
  current_connections: number;   // Current active connections
  public_key: string;            // Public key for encryption
  registered_at: string;         // ISO timestamp
  last_seen_at: string;          // ISO timestamp
  healthy: boolean;              // Health status
  failed_checks: number;         // Consecutive failed health checks
}

Health Monitoring

The health check service runs in the background and:
  1. Periodic Checks - Queries each relay’s health endpoint every 30 seconds (configurable)
  2. Failure Tracking - Increments failed_checks on timeout or error
  3. Mark Unhealthy - Sets healthy: false after 3 consecutive failures (configurable)
  4. Removal - Deletes relay after 10 consecutive failures (configurable)
  5. Recovery - Resets failed_checks and marks healthy on successful check

Health Check Request

GET {relay_url}/_health
Timeout: 5000ms
Expected response:
OK
Status: 200 OK

Geographic Routing

Clients can query relays with their location to get the closest servers:
GET /v1/relays?lat=40.7128&lon=-74.0060&limit=3
The directory:
  1. Calculates distance from client to each healthy relay
  2. Sorts by distance (ascending)
  3. Returns top N relays (default: 10)

Distance Calculation

Uses the Haversine formula for great-circle distance:
function distance(lat1, lon1, lat2, lon2) {
  const R = 6371; // Earth radius in km
  const dLat = toRad(lat2 - lat1);
  const dLon = toRad(lon2 - lon1);
  const a = Math.sin(dLat/2) * Math.sin(dLat/2) +
            Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) *
            Math.sin(dLon/2) * Math.sin(dLon/2);
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
  return R * c;
}

Bootstrap Relays

Bootstrap relays are pre-configured in the deployment config and loaded at startup:
bootstrap_relays: [
  {
    id: 'relay-us-east-1',
    url: 'wss://relay-us-east-1.fluxer.app',
    lat: 40.7128,
    lon: -74.0060,
    region: 'us-east',
    capacity: 10000,
    public_key: 'base64_encoded_key',
  },
  {
    id: 'relay-eu-west-1',
    url: 'wss://relay-eu-west-1.fluxer.app',
    lat: 51.5074,
    lon: -0.1278,
    region: 'eu-west',
    capacity: 10000,
    public_key: 'base64_encoded_key',
  },
]
Bootstrap relays ensure the directory is never empty and provide baseline coverage.

Database Schema

The SQLite database uses the following schema:
CREATE TABLE relays (
  id TEXT PRIMARY KEY,
  name TEXT NOT NULL,
  url TEXT NOT NULL,
  latitude REAL NOT NULL,
  longitude REAL NOT NULL,
  region TEXT NOT NULL,
  capacity INTEGER NOT NULL,
  current_connections INTEGER NOT NULL DEFAULT 0,
  public_key TEXT NOT NULL DEFAULT '',
  registered_at TEXT NOT NULL,
  last_seen_at TEXT NOT NULL,
  healthy INTEGER NOT NULL DEFAULT 1,
  failed_checks INTEGER NOT NULL DEFAULT 0
);

CREATE INDEX idx_relays_healthy ON relays(healthy);
CREATE INDEX idx_relays_region ON relays(region);

Relay Lifecycle

Best Practices

Relay servers should send heartbeat requests every 15-30 seconds to keep their last_seen_at timestamp current.
Relay servers must implement GET /_health endpoint that returns 200 OK when healthy.
Deploy relays in multiple regions for global coverage and lower latency.
Update current_connections regularly to help the directory balance load across relays.
Configure relay capacity based on server resources (CPU, memory, bandwidth).

Monitoring

Health Check Endpoint

GET /_health
Returns:
{
  "status": "ok",
  "timestamp": "2026-03-04T12:00:00Z"
}

Metrics

The relay directory tracks:
  • Total registered relays
  • Healthy vs unhealthy relays
  • Health check success/failure rate
  • Average response time
  • Geographic distribution

Next Steps

Endpoints

Explore relay directory endpoints

API Reference

Return to API overview

Voice Integration

Learn about voice channel integration

Deploy a Relay

Deploy your own relay server

Build docs developers (and LLMs) love