Skip to content

Running a relay

The PDS is a single Rust binary with a SQLite database, designed to be easy to host.

Every deployment exposes a health endpoint the platform can watch:

Terminal window
curl -sS https://your-pds.example.com/xrpc/_health

A healthy server reports its version, derived from the same workspace version these docs stamp, so the server and its documentation cannot claim different versions.

Custos operator console server-status screen listing version, uptime, account counts, storage, firehose state, and background-sweep last-runs
The console's server-status readout — version, uptime, account counts, storage, firehose, and background-sweep last-runs. Facts only.

On a degraded relay, the same readout flags each troubled background sweep with a trailing ! glyph and a named fault. A sweep whose last completed pass keeps aging reads stale: passes have stopped completing, so the sweep is dead. One that completed but skipped work reads failed <n>: it ran, yet recorded n errors (for blob GC, an account whose reconcile failed is skipped, so its blobs stay uncollected until the fault is fixed). Naming both keeps them legible apart on a row that has both, without relying on color.

Custos operator console server-status screen for a degraded relay, with stale background sweeps flagged by a trailing glyph
A degraded relay: stale sweeps carry a trailing ! glyph, never color alone.

A healthy server that no relay is crawling is invisible to the network, and an upstream relay can silently drop your subscription. The console’s Home screen carries a Relay federation block that compares your server’s exact sequencer head against what the upstream relay reports for your host: the relay’s lifecycle status, its cursor, how many events it is behind, and when it last consumed one. Request crawl re-invites the relay on demand: the recovery move when the readout says the relay has stopped listening.

Custos operator console home screen with a Relay federation block reporting crawling status, events behind, and a Request crawl action
The Relay federation block on Home: crawling status, exact gap, last seen — and Request crawl when it stops listening.

The same facts are served at GET /v1/admin/relay-status and the re-invite at POST /v1/admin/request-crawl — see the API reference.

  • Durability — the SQLite database is the identity store. Back it up. Production streams continuous backups to object storage with Litestream — see Backups & restore.
  • Availability — users’ clients reach your server to read and write. Health checks and restart policy are your safety net.
  • You can’t lock anyone in — you hold the lowest-precedence rotation key; the user’s device key (rotationKeys[0]) and their recovery key outrank it, so they can move their identity to another server whenever they choose. Design your operations for that.

The server deploys as an OCI image (Railway builds the Dockerfile directly). The full runbook (staging vs production branches, Litestream backups, and the security posture) lives in the repository’s docs/deploy.md.