Repository navigation
CONFIG_PG_MEMORY_OVERCOMMIT tells a PostgreSQL operator whether the backends that actually showed up could overrun the box, with what the settings permit stated beside it (#3691 lane 47) - #3907
Merged
Conversation
…s engine line says it now grades the observed worst case (#3691 lane 47) New metadata keys beside overcommit_ratio: overcommit_basis (1 observed, 0 configured), configured_overcommit_ratio, peak_backends, peak_backends_samples, observed_backend_term_bytes, observed_worst_case_bytes. OvercommitRatioLine's doc gains the sentence Erik's ruling on the D2 read requires: the line is applied to the observed ratio, and to the configured ratio only when no concurrency was observed. No constant, no scoring branch and no threshold_lineage stamp changes.
…howed up, with the configured worst case stated beside it (#3691 lane 47) Erik's ruling on the D2 read (24 of 50 measured clusters at or past 1.0 on the configured ratio, 87 % of it the max_connections backend term, peak sessions never past ~10 % of max_connections): after the host read the collector runs the existing PgTargetNumbackendsPeakSql (the statement PG_SESSION_SATURATION divides by, so the two facts cannot disagree about the peak) and forms the backend term at min(peak numbackends, max_connections). overcommit_ratio carries that observed ratio (basis 1); configured_overcommit_ratio always carries the old number. No sampled instant (pre-V133, empty pg_database_stats, a failed level read under its own degrade) keeps today's configured ratio at basis 0. Denominator unchanged.
…k backends with the configured permission as its own sentence, or the permission alone when no backend count was sampled (#3691 lane 47) Three shapes. Basis 1: the headline states the worst case at the window's peak of N backends against the host, and the investigation states the configured permission separately (the settings permit Yx if all max_connections sorted at once, a ceiling the window's concurrency never approached / approached / reached, peak N of M; a peak at or past max_connections is said to be clamped). Basis 0: the sum as today, plus the plain statement that no backend count was sampled, so the permission is what was graded. The fact-less static names the rule. Counter-objective sentences (pooler, per-role work_mem) unchanged; no DDL.
…nds: 50 of 5000 reads 0.3x with the 3.92x permission stated, 4000 fires at 0.4, no sample grades the permission, a peak over the ceiling clamps, the advice's three shapes, and a live collector read (#3691 lane 47)
This was referenced Sep 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PARTIAL for #3691 — do not close. This implements Erik's ruling on the D2 read (ruling comment; D2 measurement): "
CONFIG_PG_MEMORY_OVERCOMMITis graded on the connections that actually show up, not onmax_connections."What an operator now learns
Until now the overcommit card said "your settings permit more memory than the box has." That is true of about half the measured population: 24 of 50 Aurora clusters scored
overcommit_ratio ≥ 1.0in D2, and 87% of that worst case was the backend termmax_connections × work_mem × (1 + max_parallel_workers_per_gather). The same clusters never peaked above about 10% ofmax_connections, andnumbackendstracks the capture peak within 10%. A card that fires on half a fleet for connections that never arrive describes a permission. It says nothing about the server.The card now grades the worst case at the window's peak backend count:
pg_database_stats.numbackends. The backend term becomesmin(peak, max_connections) × work_mem × (1 + parallel), and the fact's value andovercommit_ratiohold that worst case over the window's minimummemory_total_bytes. The headline reads "The worst-case memory at the window's peak of N backends is X — R× the host's T". The investigation then states the configured permission as its own sentence: "The settings permit Y× if all max_connections sorted at once — a ceiling the window's concurrency never approached / approached (≥ 50 %) / reached (clamped, and why): peak N of M; stated, not graded."pg_database_statswindow, or a failed level read. There is no evidence of concurrency, so the permission is the only statement the store supports. It is graded exactly as before, and the card says so: "No backend count was sampled in the window … this is the configured permission … and that is what was graded."The denominator is unchanged, as ruled. On the D2 tail cluster the expected effect is 1.41 → about 0.25. A server whose real concurrency approaches its limit still fires.
Where it reads from
The peak is the existing
PgTargetNumbackendsPeakSql, the same statementPG_SESSION_SATURATIONdivides by (lane 25, #3782). It is reused, not copied, so the two facts cannot disagree about the peak. It runs as a third statement on the memory family's connection, with the same timeout, and only when there is a composition to form (terms present and at least one host sample). It sits in its own try/catch: a pre-V133 store raises 42703 onnumbackends, and that must not cost the pressure fact the host read already earned. The composition falls back to basis 0. No new SQL, no migration, no rung.Stamps (doubles-only, as always)
Always:
overcommit_basis(0/1),configured_overcommit_ratio(the old number, stated, not graded),peak_backends_samples. Only when sampled:peak_backends(raw, before the clamp, so a peak above the ceiling stays visible),observed_backend_term_bytes,observed_worst_case_bytes.peak_backends_atis omitted because the family has no time-as-double precedent. Every configured term (worst_case_bytes,backend_term_bytes, …) still rides as read.Lineage of every bar — unchanged
OvercommitRatioLine = 1.0(engine-defined,threshold_lineage = 1) andOvercommitCriticalRatio = 2.0(the chosen band, lineage 0 when it participates) keep their values and scoring branches. Only the line's doc changed: it now says the line applies to the observed ratio at basis 1 and to the configured ratio at basis 0. The collector changes which ratio sits under the key the scorer already grades.Co-fire gating — unchanged
Alone the card is still exactly the advisory base (0.4).
PG_HOST_MEMORY_PRESSUREorPG_TEMP_SPILLlifts it (0.5 each, 0.6 both, 0.7 with the band beside a co-fire). The band alone lifts nothing (D5).What it does NOT do
It does not change the denominator, either bar's value,
PG_HOST_MEMORY_PRESSURE, any rung or SQL, or the counter-objective sentences (pooler, per-rolework_mem). It adds no DDL.Pins
Harness first: net10.0 in-worktree
obj/mactest,AssemblyName=Darling.Tests, xunit.v3, against a throwawaytimescale/timescaledb:2.28.1-pg18,DARLING_TEST_PGset. Baseline before any pin: 162/162 green on Part A's product commits, live tests included. That is the proof that every existing number holds.Pins that moved: none. Every existing
PgTargetMemoryTestsfixture lands on basis 0. The unit facts passReadTerms(Snapshot())with no peak. TheSum(ratio)helper carries no basis key. The live quiet, short and stock e2e planters leavenumbackendsNULL. Those planters were deliberately not givennumbackends: at a realistic peak the quiet card stops firing and the exit-criterion pin loses its subject.New (3 facts + 1 extended):
TheGradedRatio_IsTheWindowsPeakBackends_…_AndAPeakAboveTheCeilingClamps:max_connections 5000,work_mem 4MB, host 16 GiB, peak 50 →overcommit_ratio0.30 < 1,configured_overcommit_ratio3.92 > 1, base 0, no card.peak_backendsraw 6000, the observed term equals the configured term, and the graded ratio equals the permission.TheAdvice_StatesWhichWorstCaseWasGraded_…: (v) the three shapes, composed from the stamps the real emit writes. Basis 1 is covered as never approached (exact headline), approached (4,000, and the 2,500/2,499 boundary on the 50% word) and reached (clamped, with the reason). Basis 0 says no count was sampled. The static text names the rule. Counter-objectives and no-DDL are checked on every block.AnAuroraTarget_WithSampledBackends_IsGradedAtThePeak_AndThePermissionIsStatedNotGraded: a NEW planter (PlantDatabaseStatsWithBackendsAsync) writesnumbackendsacross two databases, with a single instant peaking at 30 + 20. Through the REALPgTargetFactCollector: basis 1 at 50, 0.85×,configured_overcommit_ratio6.12. The peak and sample count equal whatPgTargetNumbackendsPeakSqlreturns on its own. Through the realanalyze_servernothing stories through the sum (all-clear);get_analysis_factsshows base 0 and the stamps.AMeasuredWindow_EmitsThePressureAndTheSum…, the natural basis-0 twin:overcommit_basis = 0,configured_overcommit_ratio == value,peak_backends_samples = 0, observed keys absent.Final local run: 196/196 green: PgTargetMemoryTests 17 (4 live), PgTargetFactCollectorTests 8, PgTargetV3PlumbingTests 3, PgTargetBetweenWavesV3Tests 8, PgTargetSharedSwitchRoutingTests 28, TsqlConventionGuardTests 14, DocCommentHygieneTests 77, RepoFileAdoptionTests 2, PgTargetThresholdLineageTests 4, PgTargetMeasuredLineageTests 4, LiveCleanupConversionRatchetTests 15, LivePostgresCollectionHygieneTests 11, FleetIdentifierScrubTests 2, StoreSqlClockDisciplineTests 3. Required checks are now
build,Darling PostgreSQL testsandLite tests (result). Windowsbuildis the first execution of the Lite/Viewer censuses.Self-review
Files:
PgTargetFactCollector.Memory.cs:MemoryTermsgains the optional peak, the derived observed term and the observed worst case; the level read and its own degrade; the fact stamps.PgTargetScorer.Memory.cs: six key constants, plus the line's doc sentence.PgTargetAdvice.Memory.cs: headline subject,ObservedSentence,ConfiguredOnlySentence, and the static text naming the rule.PgTargetMemoryTests.cs: the pins above.Riskiest hunks and their pins:
ObservedBackendTermBytes. The clamp and thePeakBackendsSamples > 0guard; a peak with 0 samples must be null, not 0 backends. Pinned by (iii) and (iv).numbackendspath is basis 0 and byte-identical.observedgate (basis > 0 && peak_backends present). A fact from before the stamp reads as basis 0. Pinned by the unchangedSum(ratio)advice fact plus the three new shapes.Reviewer checklist: the scorer's grading branch is untouched (
git diff 2f30c9faf -- PerformanceMonitor.Analysis/PgTargetScorer.Memory.csis constants and doc only). The collector adds no SQL (it reusesPgTargetNumbackendsPeakSql). The denominator is unchanged. CRLF on every .cs.