From the #2105/#2133 plan work, generalized: the aggregation shape over query_store_stats (wide, near-unique grouping keys → partials combine nothing → single-threaded finalize hash) isn't just the collapse verb's cost — it's what the store's own background jobs pay continuously, and it scales linearly with raw volume with no parallel rescue.
Measured today (dogfood store, 52 servers, 1.2–1.6M raw QS rows/day)
The four most expensive background jobs in the store are all the query_store_stats family:
| job |
last run |
| policy_compression query_store_stats |
157s |
| query_store_stats_interval_hourly refresh |
96s |
| query_store_stats_hourly refresh |
35s |
| query_store_stats_corrected_hourly refresh |
30s |
Everything else in the store is single-digit seconds. Plan analysis (full EXPLAIN in #2133's thread): ~50% serial finalize re-hash of near-unique ~160-byte keys, ~25% backward index scan over the uncompressed hot chunk, ~25% scan+partial hashing. work_mem is NOT the lever (measured: 256MB traded away parallelism and net-lost).
Why file it
Onboarding ~50 primaries ≈ 2× raw volume ≈ interval_hourly at ~3+ min and compression at ~5 min per run. Nothing breaks day one, but: refresh jobs take chunk locks that contend with collector writes (#1564/#1567 family), the CPU competes with collection sweeps (60–75s slow-sweep skips already visible), and refresh lag compounds silently if any job exceeds its cadence.
Asks
- Visibility first: surface background-job durations (job_stats last/mean duration per proc+hypertable) as self-metrics with a threshold alert — 'refresh exceeded N% of its schedule interval' is the honest tripwire. (Check overlap with V53 self-metrics before building.)
- Scale test: synthetic 2×–4× ingest on a scratch store to find the knee for the three heavy jobs.
- Structural options to evaluate (only if 1–2 say so): group keys that let partials actually combine (bucket-first aggregation), refresh cadence/window tuning for interval_hourly, and the hot-chunk access path (backward index scan vs seq).
Not urgent at 52 servers; becomes urgent the week someone points a 100-server fleet at one store.
From the #2105/#2133 plan work, generalized: the aggregation shape over
query_store_stats(wide, near-unique grouping keys → partials combine nothing → single-threaded finalize hash) isn't just the collapse verb's cost — it's what the store's own background jobs pay continuously, and it scales linearly with raw volume with no parallel rescue.Measured today (dogfood store, 52 servers, 1.2–1.6M raw QS rows/day)
The four most expensive background jobs in the store are all the query_store_stats family:
Everything else in the store is single-digit seconds. Plan analysis (full EXPLAIN in #2133's thread): ~50% serial finalize re-hash of near-unique ~160-byte keys, ~25% backward index scan over the uncompressed hot chunk, ~25% scan+partial hashing. work_mem is NOT the lever (measured: 256MB traded away parallelism and net-lost).
Why file it
Onboarding ~50 primaries ≈ 2× raw volume ≈ interval_hourly at ~3+ min and compression at ~5 min per run. Nothing breaks day one, but: refresh jobs take chunk locks that contend with collector writes (#1564/#1567 family), the CPU competes with collection sweeps (60–75s slow-sweep skips already visible), and refresh lag compounds silently if any job exceeds its cadence.
Asks
Not urgent at 52 servers; becomes urgent the week someone points a 100-server fleet at one store.