perf(bench): add a large-account seed and a request benchmark

scripts/bench/seed-large-account.ts (moved from scripts/, extended) writes
one synthetic account of ten years: 1,265,561 measurement rows across the
main types and five sources (Apple Health dense spot rows, Withings blood
pressure and scale, a weekly manual weight, three years of Oura nightly
values, 90 days of Nightscout CGM), `stats:` and per-sample cumulative rows,
nightly sleep stages, 3,020 workouts, 1,095 mood entries and three
medications with 3,285 intake events. Everything goes in through set-based
INSERT … SELECT generate_series; values and timestamps are functions of the
row index and `--anchor`, so a run is reproducible. The rollup tier is
folded with recomputeUserRollups, as the boot backfill does, and the tables
are analysed. About 80 s on the Mac mini.

scripts/bench/run.ts boots the production build once with every role (so
the queues exist), then measures against a web-only process under the
production heap ceiling: p50, p95 and max latency and SQL statements per
request (pg_stat_statements, read once nothing is in flight and the count
holds still) for /api/auth/me, the dashboard summary and snapshot, the pulse
series over 30, 365 and 3650 days, the day view, insights health status and
correlations, each cold (caches evicted by a one-row manual-sync ingest
before every request) and warm, plus a 5,000-row batch ingest as ten
requests of 500. It writes JSON and a markdown table.

docs/contributing/benchmarks.md describes the setup against a throwaway
Postgres in Docker with the production pg_stat_statements settings.
This commit is contained in:
Marc-André Bombeck committed 2026-10-22 05:38:36 +02:00
1 parent 45ea61261e
commit 375ca12b05
7 files changed
+1225 -297

No files matched your search

+1 -1
View File
@@ -4,7 +4,7 @@
* A self-hoster with 1.25 million measurement rows (a multi-year Apple Health
* export) saw the dense intra-day retention, the nightly drain tick and the
* data backup all fail with `job timed out`. Reproduced against a seeded
* account of the same size (`scripts/seed-large-account.ts`): the drains held
* account of the same size (`scripts/bench/seed-large-account.ts`): the drains held
* a type's whole history in memory before folding a day, spent about 90
* statements per folded day, and paged with a cursor Postgres could not use as
* an index condition; the backup added about 640 MB to the process to store