Skip to content

Metadata Columns Explained

Every registered check carries a set of classification metadata, set when the check is created or updated. None of this metadata makes a threshold decision by itself — it's what the evaluation layer (see How Threshold Evaluation Works in the User Guide) reads afterwards to interpret a check's collected value generically, without any per-check logic hardcoded anywhere.

Field Meaning
Internal ID The check's real, permanent identity. Every other table that refers to a specific check points at this, never at the human-readable check ID below.
Namespace / category / run number The three pieces a check ID is built from. The namespace (PGHF for built-ins, your own code for custom checks) and category are fixed forever once a check is created; the run number is the one piece you can still change later. The check ID itself — PGHF01-006-style — is computed automatically from these three, and recomputes the instant the run number changes.
Rationale Required. Why this check exists — what it catches, why it matters, and what a database administrator should do about a bad result.
Result type boolean, integer, numeric, text, or jsonb (PostgreSQL's structured, JSON-shaped data type) — the shape of the check's primary result.
Result unit A free-text unit for numeric results — percent, bytes, seconds, count, and so on.
Boolean pass value For a true/false check where one value clearly means "pass": which one. Left blank if the true/false result is purely informational, with no pass/fail meaning.
Numeric direction For a number-based check with a clear better/worse direction: lower is better, higher is better, or a specific target value is the ideal. Left blank if there's genuinely no direction — for example, a raw setting where "better" depends entirely on your own workload.
Perfect value An optional ideal value — for example, zero for an error count.
Description An optional free-form technical note — portability caveats, anything the check needs supplied to it before it runs. This is distinct from the rationale above, which is required and answers "why does this matter," not "how does this work."
Minimum / maximum PostgreSQL version An optional major-version floor and/or ceiling (for example, 17) that this check requires. Left blank on either side for no constraint on that side. Enforced by the engine itself, before the check ever runs — see Engine-level qualification below.
Required topology Whether this check only makes sense on a primary, only on a standby, or either — also enforced by the engine before the check runs, the same way as the version range above.
How to fix Optional remediation guidance for this check's finding, distinct from the rationale above (why it matters, not what to do about it). Written in Markdown, and populated on every built-in check — concrete steps and, where one exists, the actual command to run.
Execution mode polled (the default, and every built-in) or on_event — invoked standalone by a trigger the instant something happens, rather than on a scheduled cadence. See the dedicated On-Event Checks chapter — it changes enough about how a check works to warrant its own treatment rather than a table row.
Source table Required when execution mode is on_event, otherwise left blank — the table this event is about (for example pgrelay.log), purely descriptive.

The "value" convention

Every check whose result type isn't jsonb must record its primary number or answer under a key literally named "value", inside the structured data it returns when it successfully collects something. This is enforced centrally by the collection engine itself — a check that doesn't follow this fails loudly rather than silently producing data nothing downstream can read. Checks whose result type is jsonb (a structured breakdown is the whole point, with no single number that dominates) are exempt from this rule.

Percentage-of-a-ceiling checks

A raw count is often meaningless without knowing what it's being measured against — eight replication slots means something quite different on a server configured to allow ten versus one configured to allow a hundred. Where a natural ceiling exists, several checks compute a percentage as their "value" instead of the bare count: the number of replication slots in use against the maximum allowed, the worst slot's retained data against its configured limit (skipping cleanly rather than dividing by "unlimited" when that limit is turned off), and the proportion of login-capable roles that are superusers.

Not every count has a natural ceiling to divide by — the maximum number of connections a server allows, for instance, stays an absolute threshold because there's no "ceiling for a ceiling" to compare it against. The Adding Your Own Checks book has the full pattern and worked SQL examples, useful if you're writing your own checks and wondering whether a raw count or a percentage is the better choice.

Engine-level qualification

The minimum/maximum PostgreSQL version and required topology fields above are checked by the framework itself, before a check's function is ever called — different in kind from every other prerequisite a check might have (an extension, a schema, a specific table), which stays entirely the check's own job to detect and skip itself for. The line drawn: version and topology are facts about the environment the framework already knows going in; everything else is a fact only the check itself knows how to test for.

A check excluded this way still gets a "skipped" result, but its note is prefixed [engine] — a quick way to tell an engine-level exclusion apart from a check's own self-authored skip (for example, a Spock check reporting that Spock isn't installed). This carries the same "can persist silently forever" caveat as any self-skip: a long run of skips for the same check is worth periodically checking the reason for, not assumed to always be fine.

Continue to the Check Reference for every built-in check's actual rationale and how-to-fix text, or skip ahead to Reading the Catalog Without Table Access.