ATProto relay deployments#
experimental — this is a personal project for learning ATProto infrastructure. the endpoints below may go down, lose data, or change without notice. do not depend on them for anything that matters.
two full-network ATProto relays on independent Hetzner Cloud nodes with k3s:
| indigo (Go) | zlay (Zig) | |
|---|---|---|
| firehose | wss://relay.waow.tech |
wss://zlay.waow.tech |
| jetstream | wss://jetstream.waow.tech/subscribe (sidecar) |
— |
| collectiondir | sidecar on same endpoint | built-in (inspired by lightrail) |
| health | relay.waow.tech/xrpc/_health |
zlay.waow.tech/_health |
| metrics | relay-metrics.waow.tech |
zlay-metrics.waow.tech |
| source | bluesky-social/indigo | zzstoatzz.io/zlay |
try it#
both scripts are self-contained uv scripts — no virtualenv or install needed.
firehose#
consumes the raw CBOR firehose using the atproto python SDK.
# watch posts scroll by for 10 seconds
./scripts/firehose
# run longer, filter by collection
./scripts/firehose --duration 30
./scripts/firehose --collection app.bsky.feed.like
./scripts/firehose --duration 0 # forever (ctrl-c to stop)
# point at a different relay
./scripts/firehose --relay-url wss://zlay.waow.tech
./scripts/firehose --relay-url wss://bsky.network
jetstream#
consumes the simplified JSON firehose via jetstream — no atproto SDK needed, just plain websockets.
# watch all events for 10 seconds
./scripts/jetstream
# filter to specific collections
./scripts/jetstream --collection app.bsky.feed.post
./scripts/jetstream --collection app.bsky.feed.like --collection app.bsky.graph.follow
# run longer, or forever
./scripts/jetstream --duration 30
./scripts/jetstream --duration 0 # forever (ctrl-c to stop)
# point at a different jetstream instance
./scripts/jetstream --url wss://jetstream1.us-east.bsky.network
what's here#
.
├── indigo/ # Go relay (indigo) — justfile, deploy configs, terraform
├── zlay/ # zig relay (zlay) — justfile, deploy configs, terraform
├── shared/deploy/ # helm values shared by both deployments
├── scripts/ # uv scripts — firehose, jetstream, backfill
├── docs/ # architecture, deployment guide, backfill
└── justfile # root — `just indigo <recipe>` / `just zlay <recipe>`
each relay is a just module with symmetric recipes:
just indigo deploy # deploy Go relay
just indigo status # check Go relay pods
just zlay deploy # deploy zig relay
just zlay status # check zig relay pods
just --list # see all available recipes
why#
the ATProto relay is the piece of infrastructure that aggregates writes from every PDS on the network into a single firehose stream. downstream services (appviews, feed generators, labelers) subscribe to a relay instead of crawling thousands of individual servers.
running one is surprisingly cheap — the relay binary uses modest CPU and memory, and storage requirements are manageable. the main cost driver is bandwidth, which is why Hetzner (unlimited 1 Gbps) is a good fit.
this repo is a template for deploying your own. everything is declarative: terraform for the VM, helm for the workloads, a justfile to tie it together. see docs/deploying.md for setup instructions and docs/architecture.md for how the pieces fit together.
prior art#
- a full-network relay for $34 a month by bryan newbold — the definitive guide
- atproto relay any% speedrun — proof it runs on a raspberry pi
- running a PDS in kubernetes — the app-template helm pattern
- firehose.network — 3 public relays deployed globally