···33-> [hydrant](#hydrant)</br>
44-> [vs tap](#vs-tap) | [stream](#stream-behavior) | [multi-relay](#multiple-relay-support) | [crawler sources](#crawler-sources)</br>
55-> [configuration](#configuration) | [build features](#build-features)</br>
66--> [rest api](#rest-api) | [filter](#filter-management) | [ingestion](#ingestion-control) | [crawler](#crawler-management) | [firehose](#firehose-management) | [repos](#repository-management)</br>
66+-> [rest api](#rest-api) | [filter](#filter-management) | [ingestion](#ingestion-control) | [crawler](#crawler-management) | [firehose](#firehose-management) | [pds](#pds-management) | [repos](#repository-management)</br>
77-> [xrpc api](#data-access-xrpc) | [backlinks](#bluemicrocosmlinks) | [identity](#bluemicrocosmidentity) | [atproto](#comatproto) | [custom](#systemsgazehydrant)
8899# hydrant
···141141| `ENABLE_CRAWLER` | `true` if full network or crawler sources are configured, `false` otherwise | whether to actively query the network for unknown repositories. |
142142| `CRAWLER_MAX_PENDING_REPOS` | `2000` | max pending repos for crawler. |
143143| `CRAWLER_RESUME_PENDING_REPOS` | `1000` | resume threshold for crawler pending repos. |
144144+| `TRUSTED_HOSTS` | | comma-separated list of PDS hostnames to pre-assign to the `trusted` rate tier at startup. hosts not listed here use the `default` tier unless assigned via the API. |
145145+| `RATE_TIERS` | | comma-separated list of named rate tier definitions in `name:base/mul/hourly/daily` format (e.g. `trusted:5000/10.0/18000000/432000000`). built-in tiers (`default`, `trusted`) are always present and can be overridden. |
144146145147## build features
146148···284286 - returns `200 OK` if the relay was found and removed, `404 Not Found` otherwise.
285287- `DELETE /firehose/cursors`: reset the stored cursor for a given firehose relay URL. body: `{ "key": "..." }`
286288 where key is a URL. causes the next firehose connection to restart from the beginning.
289289+290290+### PDS management
291291+292292+<small>[<- back to toc](#table-of-contents)</small>
293293+294294+hydrant rate-limits firehose events per PDS. each PDS is assigned to a named
295295+rate tier that controls how aggressively hydrant limits events from it. two
296296+built-in tiers are always present: `default` (conservative limits for unknown
297297+operators) and `trusted` (higher limits for well-behaved operators). additional
298298+tiers can be defined via `RATE_TIERS`.
299299+300300+the per-second limit scales with the number of active accounts on the PDS:
301301+`max(per_second_base, accounts × per_second_account_mul)`.
302302+303303+- `GET /pds/tiers`: list all current tier assignments alongside the available
304304+ tier definitions.
305305+ - returns `{ "assignments": [{ "host": string, "tier": string }], "rate_tiers": { <name>: { "per_second_base": int, "per_second_account_mul": float, "per_hour": int, "per_day": int } } }`.
306306+ - `assignments` only contains PDSes with an explicit assignment; any PDS not
307307+ listed uses the `default` tier.
308308+- `PUT /pds/tiers`: assign a PDS to a named rate tier.
309309+ - body: `{ "host": string, "tier": string }`.
310310+ - `host` is the PDS hostname (e.g. `pds.example.com`).
311311+ - `tier` must be one of the configured tier names. returns `400` if unknown.
312312+ - assignments are persisted to the database and survive restarts.
313313+ - re-assigning the same host updates the tier in place without creating a duplicate.
314314+- `DELETE /pds/tiers`: remove an explicit tier assignment for a PDS, reverting
315315+ it to the `default` tier.
316316+ - body: `{ "host": string }`.
317317+ - returns `200` even if no assignment existed.
318318+- `GET /pds/rate-tiers`: list the available rate tier definitions.
319319+ - returns a map of tier name to `{ "per_second_base", "per_second_account_mul", "per_hour", "per_day" }`.
320320+321321+hosts listed in `TRUSTED_HOSTS` are seeded as `trusted` at startup, but only
322322+when no database assignment already exists for that host — DB entries always win.
323323+the seed is not written to the database, so it is re-applied on every restart.
324324+consequences: if you remove a host from `TRUSTED_HOSTS` and it has no DB entry,
325325+it will revert to `default` on the next restart. if you explicitly assign a host
326326+via the API (which writes to the DB), that assignment persists regardless of
327327+`TRUSTED_HOSTS`. if you delete a host's DB assignment via the API while it is
328328+still listed in `TRUSTED_HOSTS`, it will be re-seeded as `trusted` on the next
329329+restart.
287330288331### repository management
289332