Around 2026-08-20 the Bluesky relay marked every ATCR hold offline and stopped dialing. Nobody noticed for two weeks, and it surfaced only indirectly as "pull and push counts are up to 24 h stale". The stats were a symptom; the fleet was simply disconnected. It cannot recover on its own. Indigo's relay gives up on a host after 16 consecutive dial failures and returns from the redialer, and only a fresh requestCrawl revives it. The hold sends requestCrawl exactly once, at boot (server.go:400), with no ticker and no check that any relay is subscribed. So a dropped hold is invisible until its process restarts, silently. Documents the current mechanics, the failure mode, how to diagnose it with getHostStatus and a frozen repo rev, and how to recover. The automatic re-crawl is described as a deferred proposal and explicitly NOT implemented, by decision: a jittered ticker guarded on subscriber liveness, plus surfacing the subscriber count, since the deeper problem is that this was silent. Two things found while writing it, both recorded. The proposal needs plumbing that does not exist: EventBroadcaster has no exported subscriber count, and Subscriber does not retain the userAgent, so "is a relay listening" cannot currently be answered. And ResubscribeAllHosts selects only active hosts, so an offline host is not recovered even by a relay restart. Carries a replay warning.ca539b1fixed a panic on subscriber disconnect during firehose backfill, and the exposure condition is that a backfill goroutine exists at all, which Subscribe skips when the cursor is current. So a caught-up relay never triggered it and a hold whose relays are far behind is exposed on every reconnect. Verify a deployed hold containsca539b1before provoking a re-crawl;efabb677does not. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PDqoCE1j3njokkZ9b1C5n9
4.4 KiB
Known ATProto Relays
Reference list of known public ATProto relays and their capabilities, relevant to ATCR hold discovery and appview backfill.
There is no relay discovery protocol in ATProto — this list is manually maintained.
Last verified: 2026-02-08
Relay List
Bluesky (Official)
| Relay | URL | requestCrawl | listReposByCollection | Notes |
|---|---|---|---|---|
| Bluesky (load balancer) | https://bsky.network |
Yes | No (400 — not proxied) | Load balancer, proxies to regional relays |
| Bluesky US-East | https://relay1.us-east.bsky.network |
Yes | Yes | Regional relay with full collection directory |
| Bluesky US-West | https://relay1.us-west.bsky.network |
Yes | Yes | Regional relay with full collection directory |
Community
| Relay | URL | requestCrawl | listReposByCollection | Notes |
|---|---|---|---|---|
| Firehose NA | https://northamerica.firehose.network |
Yes | No (404) | 72h replay buffer |
| Firehose EU | https://europe.firehose.network |
Yes | No (404) | 72h replay buffer |
| Firehose Asia | https://asia.firehose.network |
Yes | No (404) | 72h replay buffer |
| Microcosm Montreal | https://relay.fire.hose.cam |
Yes | No (404) | |
| Microcosm France | https://relay3.fr.hose.cam |
Yes | No (404) | |
| Upcloud | https://relay.upcloud.world |
Yes | No (404) | |
| Blacksky | https://atproto.africa |
Down (502) | Down (502) | Was offline as of 2026-02-08 |
| Hayes | https://relay.hayescmd.net |
|||
| Xero | https://relay.xero.systems |
|||
| Feeds Blue | https://relay.feeds.blue |
|||
| Waow | https://relay.waow.tech |
|||
| Bassh | https://relay.bas.sh |
ATCR Usage
Hold service (requestCrawl)
The hold announces its embedded PDS to relays on startup via com.atproto.sync.requestCrawl. On startup, requestCrawls() fans out to every relay in KnownRelays (all 15 entries hardcoded in pkg/atproto/relays.go) plus any additional entries in server.relay_endpoints (a list; defaults to relay1.us-east.bsky.network and relay1.us-west.bsky.network). Per-relay failures are logged but never block startup. All healthy relays above accept requestCrawl.
That boot fan-out is the only automatic crawl request the hold makes. A relay that drops a hold (indigo marks a host offline after 16 consecutive failed dials and then stops retrying) will not pick it back up until someone requests a crawl again or the hold process restarts. See hold.md, "Relay Subscription" for the failure mode, the 2026-08-20 fleet outage it caused, and how to diagnose and recover.
Appview backfill (listReposByCollection)
The appview uses com.atproto.sync.listReposByCollection to discover DIDs with io.atcr.* records during backfill. Only Bluesky's regional relays support this endpoint. The appview's jetstream.relay_endpoints defaults to both relay1.us-east.bsky.network and relay1.us-west.bsky.network with failover between them.
Why most relays lack listReposByCollection
The listReposByCollection endpoint is not part of the relay core. It's served by a separate microservice called collectiondir that maintains an index of (collection, timestamp, DID) tuples.
Community relays running the Rainbow relay can optionally proxy to a collectiondir instance via --collectiondir-host, but most don't deploy one — likely because maintaining that index across the full network is expensive relative to just fan-out relaying.
Other useful relay endpoints
These are standard XRPC endpoints that relays may implement:
com.atproto.sync.listRepos— paginated list of all known repos (all tested relays support this)com.atproto.sync.getRepo— all tested relays 302 redirect to the source PDScom.atproto.sync.getRepoStatus— check if a relay knows about a specific DIDcom.atproto.sync.subscribeRepos— WebSocket firehose subscription