docs: add a cluster sizing guide built on hydration history - #38726
docs: add a cluster sizing guide built on hydration history#38726maheshwarip wants to merge 9 commits into
Conversation
Sizing a cluster is bounded by hydration, not steady state, and hydration cost is data-dependent enough that it cannot be read off a query plan. The durable hydration history relations now make the previous hydration measurable after the replica that ran it is gone, so the guidance can be "start large, measure, size down" rather than an estimate. Adds `/clusters/sizing/`, which opens with the existing cluster lifecycle content and then walks the procedure: create the cluster at a generous size, wait for hydration, read the episode's duration and resource peaks from `mz_replica_hydration_history` and `mz_object_hydration_history`, pick the smallest size that keeps the peak under a headroom threshold, then resize and confirm against the new episode. Includes what the recorded numbers do and do not mean, and the fallbacks when collection is disabled. The lifecycle section moves to `content/headless/cluster-lifecycle.md` so the concepts page and the sizing guide share one copy, with a pointer added to the durable history alongside the current-state relations. Reference updates: * Gate both hydration history sections on the releases that introduce them (`mz_object_hydration_history` in v26.40, `mz_replica_hydration_history` in v26.41), and document the joins a sizing query needs. * `object_count` counts every maintained compute dataflow in an episode, including the replica's system introspection dataflows, so it exceeds the number of objects a user created and does not match the row count in per-object history. Say so on the column. * `mz_cluster_replica_sizes.memory_bytes` described its unit as billionths of a vCPU core, copied from `cpu_nano_cores`. It is bytes. Every SQL example was run against the emulator. Resource peaks read `NULL` there, since they come from cgroup v2 files that a cgroup v1 host does not expose, so the peak columns in the sample output are illustrative. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E6qZnfQsyVbQ2hydYaYder
Extracting the lifecycle section carried over the blank line that separated it from the next heading, which `check-whitespace` rejects at EOF. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E6qZnfQsyVbQ2hydYaYder
Retitles the page "Optimize cluster size" and reshapes it around the questions a reader arrives with, per review. * Rewrite the intro to lead with provisioning for peak resource usage, and link out to the cluster lifecycle rather than including it. The headless fragment existed only for that include, so it goes away and the lifecycle section returns inline to the clusters concept page unchanged. * Replace the "Why hydration sets the size" section with a short note. * State the version assumption as prose: the guide assumes v26.42 or later, which is where peak resource usage during hydration became trackable. * Drop the "Choose a steady-state size" step. Its headroom query inferred a target size from a peak, which is not a rule we want to publish. Step 3 now points at `mz_cluster_replica_sizes` for the per-process memory a candidate size provides, and sizing down follows from that. * Rewrite the resize step around `ALTER CLUSTER` being graceful, and cut the paragraphs on rollback semantics, per-process peak measurement, and reading `object_count`. * Frame the remaining sections as questions, and add "How do I speed up hydration?" covering autoscaling and pointing at the hydration strategies. Both hydration history relations are gated on v26.42, which needs a release page for the shortcode to resolve, so this adds `releases/v26.42.md` with the next weekly date. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E6qZnfQsyVbQ2hydYaYder
Object history records only indexes and materialized views, so a source contributes no rows and does not hold a replica episode open. Upsert sources are the case where that matters, since they are memory-heavy enough that a reader would expect to find them. The distinction is easy to misread as "no metrics for upsert sources," so both notes say what is still measured: the replica peaks cover whole processes, so an upsert source's memory and disk are included there and a cluster hosting one is sized correctly by those peaks. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E6qZnfQsyVbQ2hydYaYder
QA LLM Review1. MEDIUM -- Guide claims replica peaks correctly size a cluster hosting an upsert source, but the episode closes before the source peaks
The guide tells readers that "a cluster hosting an upsert source is sized correctly by those peaks even though the source itself never appears per object." A replica episode is defined purely over compute exports, and its peaks are frozen at the moment the collector records it, so on the common create-source-plus-MV layout the row is written minutes into a snapshot that runs for far longer and the source's true peak is never captured. Acting on that number under-provisions the cluster. Details
Concretely: The reference page has the same overstatement in weaker form at 2. MEDIUM -- "The recorded value is never below the true hydration peak" is false for
|
Two overstatements in the interpretation guidance, both caught in review and both confirmed against the collector. An episode's peaks are read from `mz_cluster_replica_resource_usage` at the sweep's read timestamp and the row is never revised, so they cover each process from start through the moment of collection and no further. Since an episode closes on the compute dataflows alone, an upsert source's snapshot usually runs past that point and its peak is never recorded. Saying such a cluster is "sized correctly by those peaks" invites exactly the under-provisioning this guide is meant to prevent, so the note now states the real horizon and sends readers to the sampled metrics history for snapshot-driven peaks. `peak_disk_bytes` is also not an upper bound. `statvfs` exposes no kernel high-water mark, so `fs_used_peak` is folded in-process as a maximum over samples, which `DERIVED_PEAKS` documents as a lower bound on the true peak, and the collector prefers that value whenever a scratch filesystem is present. The "never below the true peak" claim now applies only to `peak_memory_bytes`, which does come from a kernel high-water mark, and disk gets its own bullet saying to leave extra headroom. This also stops the guide contradicting the column comment on the relation it links to. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E6qZnfQsyVbQ2hydYaYder
|
Verified all three against the source. Findings 1 and 2 were real and are fixed in 64c494c. Finding 3 is a deliberate call by the PR author, so I have left it. 1 — upsert source peaks (fixed). Confirmed: the 2 — 3 — version gates. Not changed, deliberately. Your version mapping matches what I originally shipped and what I put on record in this thread: Generated by Claude Code |
|
Human Pranshu here, I can confirm that this will only be announced as a part of v26.42 |
`check-whitespace` rejects it, so `lint-and-rustfmt` would have failed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E6qZnfQsyVbQ2hydYaYder
|
Why it isn't this PR's. The same job passed on Two supporting points:
No fix to port. The failure is in code this PR doesn't touch and I have no candidate fix for it. What I need. This session has no Buildkite credentials (the API and web UI both return 401/403), so I can't read the job log or spend the one re-run the flake rules allow. Could someone with access re-run I'll keep watching the PR until it's green. Generated by Claude Code |
QA LLM Review1. MEDIUM -- New step-3 sentence describes
|
`peak_memory_bytes` is the cgroup `memory.peak` high-water mark read at collection time, and nothing in the collector resets it, so it carries memory from before the episode and stops at the moment of recording. Describing it as memory usage "during the hydration event" contradicted the two bullets in this page's own interpretation section, which document both directions of error. State the horizon instead, and keep the point that matters for sizing: the value bounds the hydration peak from above rather than isolating it. The comparison against `mz_cluster_replica_sizes` also regained the per-process note. Both `memory_bytes` there and `peak_memory_bytes` here are per-process, so a multi-process size needs no multiplication. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E6qZnfQsyVbQ2hydYaYder
|
Both points fixed in 6dfade5. Main finding. Confirmed independently: Secondary. The per-process note is back on the Worth noting for anyone reading the history: this same overstatement was fixed once in 64c494c after your earlier review, then reintroduced by a later prose edit. The Separately, Generated by Claude Code |
|
Withdrawing my re-run request: Generated by Claude Code |
Docs for hydration history!