Repository navigation
Docs: record the #5794 load test results in the sizing guide - #6683
Conversation
Run 3 measured 64 GB with a faster disk, 128 GB and 256 GB at 210 servers, each with the 64 GB planner cache setting and with Darling's own value. One reader's reads met the 5 s budget only on 256 GB with Darling's value. Ten readers were refused as busy on every host. The guide now says so, and tells a bring-your-own store to reset effective_cache_size after a resize.
| This guide gives the disk, RAM and vCPU counts for a Darling store host, by the number of monitored servers. The numbers come from three production stores that we measured on 2026-10-14. A load test on a restored copy of a store will update them ([#5794](https://github.com/erikdarlingdata/PerformanceMonitor/issues/5794)). The harness and its runbook are in [`Darling/loadtest/`](../Darling/loadtest/README.md). | ||
| Audience: operators. | ||
|
|
||
| This guide gives the disk, RAM and vCPU counts for a Darling store host, by the number of monitored servers. The numbers come from three production stores that we measured on 2026-10-14. A load test on a restored copy of a store ([#5794](https://github.com/erikdarlingdata/PerformanceMonitor/issues/5794)) went to 210 servers in one store. It ran twice and is done. The test copy is torn down. This guide stays based on what was measured. The harness and its runbook are in [`Darling/loadtest/`](../Darling/loadtest/README.md). |
There was a problem hiding this comment.
"It ran twice and is done" undercounts the runs this very section documents. The page goes on to detail Run 1 (2026-10-21), Run 2 (2026-10-24) and a third round, "Run 3: larger hosts" (2026-10-24/25, reusing the run 2 build and data on resized hosts). The PR body itself says "The load-test section covers all three runs," so this intro sentence is out of sync with both the rest of the page and the PR's own account — it should say the test ran three times (or however the author wants to characterize Run 3 relative to Runs 1–2), not twice.
There was a problem hiding this comment.
Verdict: CHANGES REQUESTED
Claims
- VERIFIED — "The load-test section covers all three runs. Run 1 was on 2026-10-21 on an older build. Runs 2 and 3 were on 2026-10-24 and 2026-10-25 on
devatd659bef1a, with #6686 and the later read fixes." — the page has a Run 1/Run 2 table (docs/darling-store-sizing.md:93-96) and a "Run 3: larger hosts" subsection (docs/darling-store-sizing.md:125-153) with those dates and build. - VERIFIED — "a host with 8 vCPUs and 64 GB takes the writes and the hourly aggregate jobs for 210 servers at steady state (measured)... On the faster disk in run 3, all 16 hourly jobs finished in each sampled hour, the longest in 3 min 5 s." — matches docs/darling-store-sizing.md:98-101 and :144.
- VERIFIED — "One reader: only 256 GB with Darling's value met the 5 s budget for every read, in one of two phases." — matches the "0 in the second phase, 3 in the first" cell at docs/darling-store-sizing.md:136.
- VERIFIED — "On 128 GB and larger, the disk and the CPUs were not the limit (measured)." — matches docs/darling-store-sizing.md:143.
- VERIFIED — "The test store was bring-your-own, so Darling did not reset
effective_cache_sizeafter each resize... tells a bring-your-own operator to run--check-settings..." — matches docs/darling-store-sizing.md:138-139; the 75%-of-RAM mechanism this depends on is also confirmed in code (Darling/Darling.Tests/DarlingManagedPostgresTests.cs:1153,Darling/PerformanceMonitor.Darling.Storage/RawChunkIntervalPlanner.cs:148). - VERIFIED — "Added
Audience: operators.under the H1" — matches docs/darling-store-sizing.md:3, and is consistent with the convention already used acrossdocs/*.md(e.g.docs/darling-store-backup.md:3,docs/authentication.md:3). - UNVERIFIED — "On 128 GB with Darling's value, the 168 h regressions reads took 9 to 11 s." — this specific number is not in the diff; the Run 3 table (docs/darling-store-sizing.md:129-136) only gives aggregate "reads with p95 over 5 s" counts per host, not a per-read breakdown, so this can't be checked from the tree.
- UNVERIFIED — "#5506 was closed as not planned on 2026-10-24." — live GitHub issue state, not checkable from a read-only tree.
Riskiest lines
- docs/darling-store-sizing.md:5 — "It ran twice and is done" undercounts the runs the page itself documents (Run 1, Run 2, Run 3) and conflicts with the PR body's own "covers all three runs" — a reader skimming the intro could wrongly conclude the 256 GB/210-server finding (which comes from Run 3) predates a now-torn-down test rather than being the test's final word. UNCOVERED (prose, no test applies).
- docs/darling-store-sizing.md:149 — "On 128 GB, the 168 h regressions reads miss the budget" is stated as part of a bullet list explicitly labeled "an inference from these numbers" (line 147), but it names a specific read/number that isn't in the Run 3 table above it. Low risk since it's labeled inference, but worth the author confirming it traces to real data. UNCOVERED.
- docs/darling-store-sizing.md:131-136 — the
effective_cache_sizefigures (48,384 / 96,768 / 193,536 MB) are measured values from one specific host, not the idealized 75%-of-nominal-RAM figure (e.g. 49,152 MB for a true 64 GiB perDarlingManagedPostgresTests.cs:1153). This is consistent and expected (real hosts under-report a bit of nominal RAM) and the page already tells operators to derive the value via--check-settingsrather than copy these numbers, so risk is low. UNCOVERED.
Traps near this diff
This PR changes only docs/darling-store-sizing.md (prose/tables, no code or SQL), so the SQL, collector, analysis, alerting, storage/MCP, and test-census traps in .github/REVIEW-TRAPS.md have no surface here — there is no changed signature, constant, SQL statement or test for the CALLERS RULE to walk. The one plausibly-relevant line, "Lite and Darling ship in parity... a fix to one SKU's reader, tool, alert or description without the counterpart's is a finding," does not apply: store sizing is a Darling-only concept (a central Postgres/TimescaleDB store with a host to size), and there is no Lite equivalent doc (confirmed: no *lite*sizing* or *store-sizing* file exists under docs/ besides this one).
Divergence (blind read vs PR body)
The PR body states "The load-test section covers all three runs," which is true of the section as a whole — but the page's own opening paragraph (docs/darling-store-sizing.md:5) says the test "ran twice," which undercounts by one and contradicts both the detailed Run 1/2/3 breakdown later in the same file and the author's own characterization in the PR body. This is the one place the blind read and the author's account disagree with each other (and with the diff).
Reviewer checklist
- Confirm with the author whether "ran twice" at line 5 should become "three times" (or similar), and whether Run 3's reuse of "the run 2 build and data" (line 91) means the test copy was only torn down after Run 3, not before it as the current line 5 implies.
Claude posting for Erik Darling. Fixed in 27a3620: the intro says the test ran three times, the run table has a run 3 column, and the 128 GB row names the two slow reads.
There was a problem hiding this comment.
Verdict: LGTM
Claims
- VERIFIED — "Added
Audience: operators.under the H1, to match #6719" — docs/darling-store-sizing.md:3; grep acrossdocs/shows the sameAudience: operators.line in docs/darling-store-backup.md, docs/darling-quick-start.md and docs/retention-hold-runbook.md, so the convention matches. - VERIFIED — "Run 1 was on 2026-10-21 on an older build. Runs 2 and 3 were on 2026-10-24 and 2026-10-25 on
devatd659bef1a, with #6686 and the later read fixes" — matches the Run 1/2/3 table in the diff, docs/darling-store-sizing.md:93-97. - VERIFIED — "Ten readers: 29% to 61% of calls were refused as busy on every host" (run 3) — the five run-3 host rows (excluding the run-2 comparison row) in the busy-rate column read 46%, 29%, 61%, 55%, 49%, docs/darling-store-sizing.md:133-137 — min/max match exactly.
- VERIFIED — the quoted panel refusal, "over the limit of 6.8 million" — matches
ComposeLimits.MaxQueryStoreWideRows = 6_800_000in Darling/PerformanceMonitor.Darling.Storage/Compose/ComposeSpec.cs:41, and the message shape matches Darling/Darling.Tests/QueryStoreWideReadGuardTests.cs:72. - VERIFIED — "Darling's own value" for
effective_cache_sizescales as 75% of RAM — matches the 75%-of-RAM comments/assertions in Darling/Darling.Tests/DarlingManagedPostgresTests.cs (e.g. line 1153, "75% of 64 GB, uncapped"), and the doc's three "Darling's value" figures (48,384 / 96,768 / 193,536 MB) scale exactly 1x/2x/4x with host RAM (64/128/256 GB), docs/darling-store-sizing.md:132-137. - UNVERIFIED — "Closes #5794... The base is
dev" — PR base branch and linked-issue closure can't be confirmed from the read-only tree under this run's allowedghcommands. - UNVERIFIED — the live numbers themselves (p95 read times, busy-call percentages, disk throughput peaks, job durations) in the new load-test tables — these are results of a live test run against torn-down hosts; nothing in a read-only checkout can reproduce them.
- UNVERIFIED — "
devatd659bef1a" — this checkout is shallow (2 commits only), so the SHA can't be looked up locally. - UNVERIFIED — "#5506 was closed as not planned on 2026-10-24" — external issue state, not checkable under this run's
ghcommand allowlist (scoped to PR 6683).
Riskiest lines
- docs/darling-store-sizing.md:150 — "needs about 256 GB, with Darling's settings" is the headline capacity number operators will size new hosts against — UNCOVERED (docs-only change; no behaviour test applies, and the PR body's "CHANGELOG entry: None. Docs only." is the sentence that answers it).
- docs/darling-store-sizing.md:132-137 — the Run 3 host/
effective_cache_size/busy-rate table drives the new "use more than one store above ~150 servers" guidance — UNCOVERED (live measurement, not derivable from source). - docs/darling-store-sizing.md:143 — the quoted live panel-refusal message and its specific row/server counts — UNCOVERED, though the limit it quotes (6.8 million) is independently confirmed against
ComposeLimits.MaxQueryStoreWideRows.
Traps near this diff
- Repository mechanics: "Lite and Darling ship in parity... a fix to one SKU's reader, tool, alert or description without the counterpart's is a finding" — does not apply. docs/darling-store-sizing.md is inherently Darling-only (TimescaleDB multi-server store sizing);
find docs -iname "*sizing*"returns only this one file, and Lite is a single-host DuckDB app with no comparable multi-server store to size. - Workflows: "
claude-code-actionrefuses to run when.github/workflows/claude-review.ymldiffers from the default branch's copy" — does not apply, this diff touches onlydocs/darling-store-sizing.md.
Divergence (blind read vs PR body)
None — the body's account matches the diff on every claim graded above, including the precise 29%-to-61% busy-rate range for the run-3 hosts and the effective_cache_size scaling.
Claude posting for Erik Darling.
Closes #5794. The base is
dev, so the issue is closed by hand at merge.What changed in
docs/darling-store-sizing.mddevatd659bef1a, with Use the measured purge-edge margin in the Query Store regressions read (part of #5506) #6686 and the later read fixes.effective_cache_sizeafter each resize. The page says so. It also tells a bring-your-own operator to run--check-settingsafter a resize and set the value it derives.Audience: operators.under the H1, to match docs: add docs/README.md index and audience tags (part of #6420) #6719.CHANGELOG entry
None. Docs only.