zds-pds's resident memory climbs from about 230 MB after a restart to the 1 GB machine ceiling within days. The process then gets SIGKILLed, and the shared CPU also ran out of burst. This blocks moving zzstoatzz.io onto any zds host until we know why.
Fly metrics for zds-pds (shared-cpu-1x, 1 GB, ord, 24 accounts), 2026-10-28 to 2026-11-09. That's all Fly keeps:
| zds-pds | pds-zzstoatzz-io (Bluesky PDS, 1 account), for comparison | |
|---|---|---|
| memory used, avg / max of 987 MB | 505 / 965 MB | 390 / 491 MB |
| days at the ceiling | 6 of 11 | 0 |
memory_pressure_some peak, 10 s average |
86% | 0% |
| CPU busy, avg / p99 / max | 4.3% / 41% / 98% | 0.6% / 1.8% / 32% |
| CPU throttle | every day 10-29 → 11-03, cpu_balance at its 0.5 floor |
none |
| restarts | 23 | 1 |
| HTTP 200s | 297,981 | 357,547 |
| bytes sent | 37.2 GB, 12.8 GB of it via the edge | 11.1 GB |
restarts and kills
- 18 restarts line up with releases v351–v370.
fly_instance_exit_codewas 137 on 10-31 22:35 and on 11-04 02:25 UTC.fly_instance_exit_oomwas set at 11-04 02:25.- Three more restarts match no release: 10-29 02:50, 11-05 09:40 and 11-07 01:10. Their exit reason wasn't recorded, because the gauges don't change on a repeat value.
- Since the redeploy on 11-08, memory has been flat at about 232 MB.
Daily max memory (MB): 10-29 939 · 10-30 706 · 10-31 841 · 11-01 964 · 11-02 879 · 11-03 565 · 11-04 964 · 11-05 895 · 11-06 964 · 11-07 964 · 11-08 232
other things on the volume
/datais 1.34 GB used of 20 GB, and that figure was flat over the window./data/blobsis 190 MB.zds.sqlite3is 720 MB, plus a 296 MB WAL.- About 100 MB of leftover
zds-snapshot.part.*andzds-snapshot.sqlite3.gzfiles are still in/data. - About 24 GB was sent over 11 days without passing through Fly's edge. I haven't found what sends it.
how to reproduce the queries
Fly's Prometheus endpoint needs Authorization: FlyV1 $(fly auth token). Bearer returns 401 "something went wrong resolving organization".
max_over_time((fly_instance_memory_mem_total{app="zds-pds"} - fly_instance_memory_mem_available{app="zds-pds"})[1d:1m])
fly_instance_exit_code{app="zds-pds"}
fly_instance_cpu_balance{app="zds-pds"}
against https://api.fly.io/prometheus/personal/api/v1/query_range.
Questions:
- Is the climb a leak, an unbounded cache (blocks, MST nodes, event backfill, firehose subscribers), or sqlite page cache that
mem_availabledoesn't count as reclaimable? - Does it track request volume or uptime? Adding zzstoatzz.io would roughly double the requests.
- What drives the CPU bursts that drained the throttle balance from 10-29 to 11-03?
The climb was a leak, fixed in 0.7.4 (
c676048, live since 11-07 04:32 UTC).describeRepo,getRecordandlistRecordsallocated their results withpage_allocatorand never freed them, so every public read kept its memory. Before the fix, memory grew about 20 MB an hour in a straight line (194 → 1011 MB on 11-05/06), and page cache stayed at 50–84 MB. Since the fix, memory has gone from 195 to 221 MB over 20 hours, about 10 MB of which is sqlite page cache.Follow-up checks, shipped in 0.7.6 (Fly v371):
getByUri, but nothing called it. It's deleted, along with about 450 lines of other unused code.listRecords/describeReporeads moved RSS from 30.6 to 31.3 MB.Still open: