Postgres Monitoring

A self learning, self reasoning monitoring agent for highly available PostgreSQL clusters
Architecture, Learning and Reasoning Guide
Postgres Monitoring / Learning and reasoning

Before the
Pager Rings.

How local monitoring turns observations into memory, weighs evidence and brings useful context to the person responsible for the database.

Overview

What would database monitoring look like if it remembered the past, explained unusual behavior and brought relevant operational knowledge to each investigation?

Static thresholds remain valuable, but they rarely tell the whole story. A familiar daily peak can look alarming, while a gradual change can pass unnoticed. Historical context offers another perspective: not just whether a number is high, but whether it is unusual for this workload.

This article explores a local monitoring design that combines deterministic checks, persistent history, a small numeric predictor and runbook retrieval. Bash and AWK provide one lightweight implementation path. Database clients, operating system utilities and any optional storage extensions still need to be installed and managed.

Article scope: Document records, incident identifiers and numerical examples are synthetic. Schedules, retention periods and thresholds require workload-specific validation.

The Constraint We Designed For

In restricted production environments, access to external language models may be unavailable, and sensitive database information must remain within the approved infrastructure.

This constraint does not rule out useful learning. A small numeric model can run locally, while a retrieval layer can find relevant runbooks without generating an explanation. These are separate capabilities: one estimates risk from measurements, and the other supplies documented context for a person to review.

The broader lesson is that model size is only one part of reliability. Persistent evidence, meaningful labels and careful evaluation can matter just as much. Whether a smaller local approach is sufficient depends on the failure scenarios it must handle.

Stays local

Measurements, learned weights and operational knowledge can remain within approved infrastructure. Local execution still requires access controls and resource limits.

Stays explainable

Every prediction can be traced to a formula, a weight and a row of history. Nothing is a black box.

Stays safe

Learning can only make alerts more sensitive, never less, and the agent never takes an action based on retrieved text.

Architecture

A primary and standby with a connection pool provide one useful example. Other topologies can use the same principles: explicit monitoring ownership, persistent observations and clear boundaries between advice and action.

Applications connect through the virtual IP address Pgpool with Watchdog connection pooling, health checks, failover Primary Node PostgreSQL primary VIP ownership checked separately twenty minute monitoring run Standby Node PostgreSQL hot standby ready to be promoted main cycle runs only on VIP owner streaming replication carries the shared learning tables Log Monitor polls logs every five minutes Split Brain Monitor checks roles every three minutes Root Cause Engine launched on every switchover
Physical and logical architecture of the monitored cluster

The useful pattern is a division of responsibilities: periodic health checks build a broad picture, more frequent observations catch urgent changes, and incident review explains how events unfolded. Collection intervals should follow workload sensitivity and monitoring cost rather than a fixed schedule copied from another deployment.

Data Flow in Three Dimensions

Each run moves data upward through five layers. Drag the model to rotate it.

1. Collectpg_stat_activitypg_stat_replicationprocessor and memorydisk and socketsPgpool nodes
2. Remembermoving average baselinesfeature historyshared history table
3. Learnself labellingadaptive thresholdsweekly gradient step
4. Reasonattention predictornoise gaterunbook retrievalincident timeline
5. Actearly warning pagereportmorning forecast
Drag to rotate

Drag with a mouse or one finger to rotate. Select a layer to inspect its inputs, decisions and failure boundaries. This is an explanatory model, not live production telemetry.

Raw measurements enter at the bottom. They are smoothed into baselines and written into history, which is where memory lives. The learning layer turns that history into labels, thresholds and weights. The reasoning layer combines all of it into a judgement about the next hour, and only the top layer ever reaches a human.

The Monitoring Cycle

A useful sequence is to collect evidence, compare it with history, update memory and report findings. The diagram uses a twenty minute interval as a worked example, not a required schedule.

Owns theaddress? No: exit quietly Cron triggerevery twenty minutes Load configurationvalidate every setting Read local addressesexact IPv4 comparison VIP ownership gatebefore runtime setup Lock and snapshotbefore any check runs Run health checkshost, database, middleware Update baselinesmoving averages Detect anomaliescurrent against snapshot Log feature rowand label an older row Adaptive thresholdslast 72 runs Predict next hourattention forward pass Gate, report, alertwith runbook context Yes
The main monitoring cycle as a flowchart

Two details in this cycle matter more than they look. First, the baseline is copied before any check runs, so anomaly detection compares this run against history rather than against a baseline that already contains this run. Without that snapshot every spike would partly hide itself. Second, every stage after the checks is wrapped so that a failure in learning or prediction can never stop the monitoring itself. If the intelligence layer breaks, the agent falls back to plain threshold alerting and keeps paging.

What We Check

A monitoring plan should cover the host, database, middleware and topology. These areas provide a starting point rather than a completeness guarantee. Select checks according to the workload and its failure modes.

AreaWhat is covered
ServerPostgreSQL process count, processor utilisation measured between runs, memory pressure and swap, disk input and output latency, network errors, and out of memory killer events.
DatabaseReplication lag in bytes and seconds, connections, idle and idle in transaction sessions, lock waits, deadlocks, long running queries, table and toast bloat, autovacuum pressure, transaction identifier wraparound, checkpoint pressure, buffer and cache hit ratios, write ahead log volume and archiving, temporary files, storage growth, statement statistics, sequence exhaustion, settings drift, log errors, replication slots, transactions per second trend, unused and invalid indexes, prepared transactions, replication conflicts, crash restarts, clock drift, orphan temporary files, backup freshness, encrypted connections, logical subscriptions and stale statistics.
MiddlewarePgpool backend node status, connection pool usage, Pgpool process health, Pgpool log errors, and watchdog quorum.
TopologySplit brain detection, virtual address and primary mismatch, PostgreSQL service state, Pgpool service state, and address name resolution.
CorrelationGhost connections found by comparing operating system sockets against database sessions, and anomaly detection across every tracked baseline.

How the Learning Works

Six stages connect observation, memory and learning. The animation shows the conceptual flow, not the timing of an actual monitoring run.

Animated learning cycle Particles travel clockwise through observe, smooth, label, adapt, predict and recalibrate. Smaller particles connect these stages to persistent memory at the centre. Memory history of every run 1. Observecollect metrics 2. Smoothmoving average baseline 3. Labeloutcome one hour later 4. Adapttighten thresholds 5. Predictattention forward pass 6. Recalibrateweekly gradient step
Moving particles trace the learning cycle. The centre represents persistent history used across stages. The raised view shows conceptual movement rather than elapsed processing time.

Stage one and two: observing and smoothing

An exponential moving average lets recent readings influence the baseline without replacing all of its history. With a smoothing factor of 0.2, the current reading contributes one fifth of the next baseline. A spike still moves that baseline, which is why detection should compare against a snapshot taken before the update. The smoothing factor and collection interval together determine how quickly the baseline adapts.

new baseline = 0.2 × current value + 0.8 × previous baseline

A metric is flagged as an anomaly when its current value reaches 150 percent of the baseline captured before the run. When the processor, input and output latency, connection usage and replication lag are anomalous together, the agent raises a composite alert, because that combination is the classic signature of a cascade that ends in failover.

Stage three: labelling itself

Learning needs labels, and nobody has time to label twenty minute rows by hand. So the agent labels its own history. Every run appends a feature row with the health score, the warning and critical counts, and the smoothed processor, connection, replication lag and disk values. The outcome column is left empty. Three runs later, about an hour on, the agent fills that empty outcome with whatever the cluster status turned out to be. Each row therefore answers the question that matters: given what things looked like, what happened in the next hour.

Stage four: adaptive thresholds

Once a day of history exists, which is seventy two rows, the agent computes a threshold for each metric from the last seventy two runs.

adaptive threshold = mean + 2σ     final threshold = the lower of the adaptive value and the configured value

The safety rule is deliberate. Adaptive thresholds can only tighten an alert line, never loosen it past what an engineer configured. If the cluster is normally quiet, the agent notices trouble earlier. If the cluster is normally busy, the configured limit still stands.

Stage five: prediction

A small predictor can combine recent and historical pressure into a risk score. The example below uses a warning boundary of seventy out of one hundred. Such a score is not automatically a calibrated probability, and a forecast horizon is not a guaranteed warning time. Both need evaluation against independently observed incidents.

Stage six: weekly recalibration

Recalibration can run periodically once enough labelled outcomes exist. In this example, healthy, warning and critical outcomes map to targets of 0, 0.5 and 1. The learner measures prediction error and takes a small gradient step on each weight. The appropriate cadence depends on how quickly the workload changes and how much trustworthy evidence is available.

error = target − prediction     new weight = weight + 0.01 × average(error × normalised feature)

Weights are then clipped between 0.05 and 0.70 so no single metric can take over or disappear, and normalised so they add up to one. The learning rate is small on purpose. We would rather the model drift slowly toward the truth than swing on one bad week. The mean squared error before the update is recorded with the new weights, so every recalibration leaves an audit trail.

The Attention Predictor

A shell native encoder and decoder that looks at four windows of time at once and decides how much each one should count.

Drag to rotate
Drag the chart to rotate it. The controls below change its temporal weights and reveal their effect on an illustrative risk score.

The sliders change fixed time window weights, not the four learned metric weights. Values are normalized before comparison. The scenario uses synthetic window summaries and does not train or modify the monitoring agent.

HeadWindowRows readAttention weightWhat it captures
OneLast two hours60.4What is happening right now
TwoLast six hours180.3The shape of the current shift
ThreeLast day720.2Daily rhythm such as the morning peak
FourLast week5040.1Weekly rhythm such as weekend batch work

Encoder

Each head averages the processor, connection, replication lag and disk values across its window. The four averages are blended using the attention weights, so recent behaviour counts most but the daily and weekly patterns still pull on the result.

encoded metric = Σ (head weight × average of that metric over the head window)

The encoded metric is one blended measurement, such as processor usage. The symbol Σ means add the contributions from all time windows. A head is simply one window of history. Its weight controls how much that window contributes, while its average is the mean of the measurements collected within that window. These temporal weights are distinct from the metric weights used in the next formula.

For example, processor averages of 80, 60, 40 and 20 percent across the four windows, with weights of 0.4, 0.3, 0.2 and 0.1, give 0.4 × 80 + 0.3 × 60 + 0.2 × 40 + 0.1 × 20 = 60 percent. The result remains in the original metric units.

Decoder

Each encoded metric is normalised against its ceiling, with 500 megabytes as the ceiling for replication lag and 100 percent for the others, and then projected into a single risk score using the learned weights. The starting weights are 0.35 for processor, 0.30 for connections, 0.20 for replication lag and 0.15 for disk, and the weekly recalibration moves them from there.

risk = wprocessor·xprocessor + wconnections·xconnections + wlag·xlag + wdisk·xdisk

Here, w is the learned importance of a metric, x is its encoded measurement divided by a reference scale, and the dot means multiplication. The small labels identify processor utilisation, connection utilisation, replication lag and disk utilisation. Adding the four contributions produces a dimensionless risk score.

TermMeaning in this example
xprocessorBlended processor utilisation divided by 100 percent.
xconnectionsBlended connection utilisation divided by 100 percent. A connection count must first be converted to a percentage of capacity.
xlagBlended replication lag divided by the example scale of 500 megabytes. This scale is a design choice, not a universal safe limit.
xdiskBlended disk utilisation divided by 100 percent.
w for each metricThe relative contribution learned for that metric. The four weights are normalised to sum to one.

For example, normalised measurements of 0.60, 0.50, 0.20 and 0.70 with weights of 0.35, 0.30, 0.20 and 0.15 produce a risk score of 0.505. Multiplying by 100 gives 50.5 on a display scale. It does not establish a 50.5 percent chance of failure. A measurement above its reference scale can exceed one, so clipping and interpretation must be explicit.

The risk score is split into three probabilities. The critical probability rises directly with risk. Between a risk of 0.3 and 0.7 there is a transition zone where the degraded probability peaks and then fades, so the three classes each own a clear region with a shared middle ground for ambiguous readings. The result is written to state after every run and reused by the morning briefing, which labels the day ahead as low, moderate, elevated or high risk.

How the Reasoning Works

Every candidate alert passes through a chain of judgements before it reaches a person.

Signal crosses a line Is it critical? High availabilitysafety key? Critical risk under 40%and value within P90? Page immediately Always page, never gated Hold back, log onlypredictable noise Keep warning and guidancenotification policy still applies Result joins memory YesYesYesNoNoNo
Alert reasoning. The gate can only hold back routine warnings, never anything that threatens availability.

The noise gate

A warning is held back only when every one of these is true at once: the gate is switched on, there is at least a day of history, the predicted critical probability is below forty percent, and the current value sits inside its own historical ninetieth percentile. If any condition fails, or if anything inside the gate errors, the warning is sent. The gate fails open by design, and it first ran in observe only mode so we could see what it would have suppressed before trusting it.

Keys that are never suppressed

Split brain, virtual address mismatch, stopped replication, inactive replication slots, missing monitor heartbeats, broken idle connections, transaction identifier wraparound, sequence exhaustion, out of memory kills and database log errors can never be held back, whatever the model thinks. Critical alerts never enter the gate at all.

Reasoning after a failover

When the primary changes, the root cause engine reads the full day of logs, keeps only the lines from that date, and rebuilds a chronological timeline of what the agent saw against what actually happened. It matches the log patterns against sixty three known signatures, attaches the related informations, and writes recommendations. That timeline then becomes part of memory, so incidents turn into learning rather than just alerts.

Cluster Wide Memory

Memory should survive a process restart or a change of primary. Shared storage can help, but its availability and completeness still need checking.

One approach is to write observations locally and copy them into a PostgreSQL history table. A newly active monitor can rebuild local history from the replicated data when it is available. Recovery depends on replication progress, retained rows and database connectivity. Local storage also needs capacity checks and a clear policy for retrying failed writes.

TimescaleDB is an optional choice for time series management, while pgvector can support knowledge retrieval. Neither is required for basic persistent history. Seeing effects across services requires aligned observations and relevant service events; putting records in the same database does not by itself establish causality.

StoreWhat it holdsWhy it lives there
Feature history fileOne labelled row per run, twenty eight daysFast, local, always writable even when the database is down
Shared history tableThe same rows for every nodeReplicated, so memory follows the primary
Optional time series extensionAligned observations over timeRetention and aggregation alongside the PostgreSQL history table
Vector storeReviewed passages, numeric vectors, source revisions and verification datesRetrieves relevant incident and runbook context using the same representation as the alert query
Learned weightsCurrent predictor weights and last errorAudit trail of every recalibration

Reasoning from Operational Evidence

The reasoning layer brings together previous incident reviews, log evidence, monitoring history and runbooks. It uses current symptoms to find relevant operational context and presents that evidence with its source.

Two paths work together. Deterministic mappings connect known alert keys and log signatures to investigation guidance. Vector retrieval searches approved incident and runbook passages for similar symptoms, including context not covered by a direct mapping. Neither a rule match nor a vector score proves the root cause.

Evidence inSelectionContext out
Alert key, for example repl_lag_mb_RUNBOOK_HINT_MAP selects pg_replication_lag.md; _runbook_inject() reads the relevant headings.Probable causes, investigation steps, immediate actions and long-term remediation in the report and alert file, subject to the normal notification gates.
Incident log lines, for example could not receive data from WALRUNBOOK_MAP in the root cause engine associates known log patterns with runbooks.Matched operational guidance alongside incident analysis. A match is supporting evidence, not proof of causality.
Alert description and sanitized log evidenceThe retrieval application tokenizes the symptom text, constructs a query vector and searches compatible passage rows in PostgreSQL.Relevant incident and runbook passages with source identifiers, revisions and similarity scores.

The deterministic path remains available when the vector database is unavailable or no suitable passage is found. Retrieval adds context; it does not delay the original alert or authorize a remediation command.

Documents to pgvector

The indexing application reads approved incident reviews, sanitized log excerpts and runbooks. It separates documents into passages, records their source and revision, and converts the text into numeric vectors. PostgreSQL stores the readable text and metadata alongside each vector. The pgvector extension supplies the vector type and distance operators; the application owns tokenization, weighting and document lifecycle.

Indexing: approved document revision Retrieval: alert or incident evidence Reviewed documentsrunbooks, incident reviews Split by headingone passage per section Tokenisetechnical terms kept whole Weight and normalisesparse term vector Alert fireskey, metric, log signature Build symptom querysame tokeniser Query vectorsame vocabulary and IDF Ranked passagestext, revision, distance pgvectorpassage vectors annotates the alert only, never triggers an action
Document text becomes indexed vectors; event evidence becomes a query vector; PostgreSQL returns matching passage text and provenance. Indexing processes approved revisions, while retrieval runs as part of alert or incident enrichment.

From evidence to a matching passage

Indexing and retrieval. The indexing application produces the numbers. PostgreSQL stores those numbers alongside the source text and revision; pgvector does not tokenize documents.

Tokens and the Symptom Query

Tokenization happens in the indexing application, not inside pgvector. pgvector stores numeric vectors and supplies distance operators; it does not read or tokenize documents.

First remove secrets and identify the document, revision, product version and section. Split at headings while retaining enough surrounding context to understand each passage. Preserve the original passage text separately from the token list: the engineer must receive readable evidence, not a vector.

How text becomes tokens

StepWhat happensWhy
Lower caseAll text is folded to lower caseSo Replication and replication are the same term
SplitText is split on anything that is not a letter, digit or underscoreKeeps names such as pg_stat_replication and max_connections whole
Keep codesError codes, setting names and metric names are kept as single tokensThese are the most precise signals in any incident
Drop fillerCommon words such as the, and, with and is are removedThey carry no diagnostic meaning
WeightEach token is weighted by how often it appears in the passage and how rare it is across the corpusRare, specific words count far more than common ones
NormaliseThe vector is scaled to unit lengthSo long and short passages compete fairly
weight(term) = count(term in passage) × [1 + ln((1 + passage count) ÷ (1 + passages containing term))]

This example uses smoothed TF-IDF. Freeze a vocabulary that assigns one coordinate to each retained token, calculate IDF from the indexed corpus, and save both with a representation version. Divide each nonzero vector by its Euclidean length. Documents and queries must use the same coordinate order, IDF values and tokenizer version. Skip zero vectors; they have no usable cosine direction.

A small, reproducible example

Two short passages keep every coordinate visible: passage A comes from an incident review, and passage B from a runbook. Their identifiers and content are demonstration data, not production records.

Incident passage A: "Replication lag on standby"
Runbook passage B:  "Connection limit reached"
After lowercase and removal of "on":
  A tokens: replication, lag, standby
  B tokens: connection, limit, reached

Frozen coordinate order:
  [replication, lag, standby, connection, limit, reached]
N = 2 passages; each term occurs in 1 passage
IDF for each term = 1 + ln(3 / 2)

Normalized A = [0.577350, 0.577350, 0.577350, 0, 0, 0]
Normalized B = [0, 0, 0, 0.577350, 0.577350, 0.577350]
Query "replication lag":
  Q = [0.707107, 0.707107, 0, 0, 0, 0]
Cosine similarity(Q, A) = approximately 0.816497
Cosine similarity(Q, B) = 0

The six coordinates are only for this worked example. A real vocabulary is much larger; select a supported vector type and dimension after measuring it. Out-of-vocabulary query terms do not receive invented coordinates. A changed vocabulary or IDF snapshot requires a new representation and consistent reindexing.

How an alert becomes a query

The alert-enrichment path combines the alert key, metric description, relevant sanitized log excerpt and severity into symptom text. It applies the saved tokenizer, vocabulary and IDF snapshot. Incident analysis uses the same path with the relevant incident evidence.

alert key         repl_lag_mb
metric            replication lag in megabytes on the standby
log signature     could not receive data from WAL stream
severity          warning

query tokens      repl_lag_mb  replication  lag  megabytes  standby  receive  data  wal  stream  warning

These are candidate tokens before vocabulary lookup. Technical names can improve exact matching, but synonyms, ambiguous terms and application-specific wording can still cause misses. Unknown terms or a zero query vector should produce no vector result; existing deterministic runbook selection should continue.

What PostgreSQL stores

The database stores one row per passage, not one opaque vector for an entire incident. The application supplies already-normalized coordinates. Each row keeps the readable passage, its source, revision and representation version alongside the numbers. This compact example uses six dimensions so the complete stored values fit on the page.

CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE knowledge_passage_example (
    passage_id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    source_id TEXT NOT NULL,
    revision TEXT NOT NULL,
    section TEXT NOT NULL,
    content TEXT NOT NULL,
    representation_version TEXT NOT NULL,
    verified_at TIMESTAMPTZ,
    active BOOLEAN NOT NULL DEFAULT true,
    embedding vector(6) NOT NULL
);

INSERT INTO knowledge_passage_example
    (source_id, revision, section, content, representation_version, embedding)
VALUES
    ('incident-demo-001', 'r1', 'Symptoms', 'Replication lag on standby',
     'tfidf-demo-v1', '[0.577350,0.577350,0.577350,0,0,0]'),
    ('runbook-demo-connections', 'r1', 'Symptoms', 'Connection limit reached',
     'tfidf-demo-v1', '[0,0,0,0.577350,0.577350,0.577350]');

Inspecting the stored rows shows that vectorization does not replace the original evidence:

SELECT passage_id, source_id, content, embedding
FROM knowledge_passage_example
ORDER BY passage_id;

passage_id: 1
source_id:  incident-demo-001
content:    Replication lag on standby
embedding:  [0.57735,0.57735,0.57735,0,0,0]

passage_id: 2
source_id:  runbook-demo-connections
content:    Connection limit reached
embedding:  [0,0,0,0.57735,0.57735,0.57735]

These identifiers assume a newly created example table. The vector(6) column stores six single-precision numbers in PostgreSQL's vector representation. The bracketed text is its SQL input/output form, not a separate JSON document. Source metadata and passage text remain ordinary relational columns. The vector value uses 32 bytes for six dimensions under pgvector's 4 × dimensions + 8 storage formula, excluding row, text, metadata and index overhead.

Retrieval during an alert or incident

The application binds the query vector as $1 and its representation version as $2. The <=> operator is cosine distance: smaller is closer. This exact-search example needs no approximate index. A production integration must also restrict results to authorized sources and compatible component versions.

SELECT passage_id, source_id, revision, section, content, verified_at,
       1 - (embedding <=> $1::vector(6)) AS similarity
FROM knowledge_passage_example
WHERE active AND representation_version = $2
ORDER BY embedding <=> $1::vector(6)
LIMIT 3;

Example one: replication-lag alert

The symptom replication lag becomes [0.707107,0.707107,0,0,0,0]. With the matching representation version, the query returns these approximate scores:

SourceCosine distanceSimilarityReturned text
incident-demo-0010.18350.8165Replication lag on standby
runbook-demo-connections1.00000.0000Connection limit reached

The enrichment layer rejects the unrelated second result. Using 0.60 as a demonstration minimum similarity, it attaches the first passage as evidence:

{
  "event_id": "demo-alert-001",
  "alert_key": "repl_lag_mb",
  "query_text": "replication lag",
  "representation_version": "tfidf-demo-v1",
  "matches": [{
    "passage_id": 1,
    "source_id": "incident-demo-001",
    "revision": "r1",
    "section": "Symptoms",
    "content": "Replication lag on standby",
    "similarity": 0.8165,
    "verified_at": null
  }]
}

The unknown verification date stays visible. This tiny symptom passage is context, not a complete remediation runbook or a confirmed diagnosis. Real passages retain enough investigation detail to support an engineer's next decision.

Example two: connection-limit incident

The symptom connection limit becomes [0,0,0,0.707107,0.707107,0]. The same query ranks the connection runbook at similarity 0.8165 and the replication incident at 0.0000. The stored rows do not change; the event's vector changes which passage is retrieved.

LIMIT 3 is not a relevance guarantee. The enrichment layer applies a validated minimum score and permits an empty result. For example, a query containing only checkpoint has no coordinates in this toy vocabulary, so the application skips vector search instead of submitting a zero vector. Database errors or unavailable vectors do not block the original alert. Retrieved text never authorizes an automatic action.

Ranking and Ageing

Similarity measures a text match, not correctness. Verification age is additional context, not a guarantee of trust.

The database query orders compatible passage vectors by cosine distance. The enrichment application then applies its verification-age policy to eligible results. This reranking is application logic, not automatic behavior supplied by pgvector. The two worked examples above show the raw similarity before any age adjustment.

similarity = (query · passage) ÷ (|query| × |passage|)
freshness = 1 ÷ (1 + days since last verified ÷ 180)     final score = similarity × freshness

With this illustrative factor, verification 180 days ago halves the score. An older passage can still outrank a newer, less similar passage; the formula does not prohibit that. Filter incompatible or superseded guidance separately, and leave an unknown verification date visible rather than treating it as fresh. Both the age scale and relevance threshold need evaluation.

Days since verifiedFreshness factorEffect
01.00Full weight
900.67Still competitive
1800.50Needs a strong match to lead
3650.33About one third of the similarity score

Where the ranking has limits

TF-IDF can miss synonyms and application-specific wording. A local encoder is another design option, but its quality, runtime dependencies and security approval need evaluation. A different dimension can require schema and index changes. Re-encode documents and queries consistently before comparing results on held-out incident queries.

Storage types, distance operators and index limits are documented in the official pgvector reference. The worked SQL uses exact search; approximate indexes trade some recall for speed and need separate validation.

Revisions and Re Embedding

Changed content passes review before the indexer publishes a consistent searchable version.

The indexer fingerprints document content with a checksum. For an approved changed revision, it regenerates passages and vectors, then atomically activates the new rows and retires the previous rows from active search. Prior revisions and retrieval records remain available for incident audit. A checksum identifies changed bytes, not an obsolete recommendation; operational review remains separate.

A content-only change can use the frozen vocabulary and IDF snapshot. Changing either requires reindexing the corpus under a new representation version. An engineer must verify operational accuracy and software compatibility independently of the checksum.

Feedback and Precision

Incident review connects what the agent reported with independently observed outcomes.

The enrichment record captures the incident identifier and exact passage revisions returned. Engineers record whether the page was justified and whether its context helped. The compact table below stores those verdicts; its document references identify the retrieved revisions. Alert correctness and passage usefulness are separate judgements.

CREATE TABLE page_feedback (
    incident_id     TEXT PRIMARY KEY,
    alert_key       TEXT        NOT NULL,
    verdict         BOOLEAN     NOT NULL,
    retrieved_docs  TEXT[],
    doc_helpful     BOOLEAN,
    reviewed_by     TEXT        NOT NULL,
    reviewed_at     TIMESTAMPTZ NOT NULL DEFAULT now()
);

Later monitoring status supplies proxy labels for numeric recalibration. Engineer verdicts are retained separately as evaluation evidence rather than silently replacing those labels. An unreviewed page remains unknown, not a negative example. Any training process that uses reviewed outcomes must distinguish them from proxy labels.

What we measure

Pages per week
The simplest measure of pager fatigue
True positive ratio
Tracked per metric and per retrieved document
Lead time
How early the pages that were right actually arrived

The evaluation report tracks precision and flags passages with repeated unhelpful verdicts for review. A false page does not by itself prove its attached document was misleading. Document-feedback evaluation is separate from the weekly numeric gradient update.

Catching silent misses

Incident review should compare what paged against independently observed impact. Record an incident with no corresponding alert as a possible miss, then investigate telemetry, routing and threshold behavior before attributing it to the predictor.

Classifying Misses

Incident reviewers classify a miss by where evidence was lost or misinterpreted before choosing a correction.

Miss loggedfrom incident review Metric moved but stayed under the linethreshold problem Metric barely moved, impact was realfeature gap, missing context Page fired, context wrong or missingcorpus problem Review threshold and labelsevaluate a candidate correction Add a new feature columnpredictor input widens Review source and selectioncheck both content and retrieval
Miss classification decides whether to let recalibration work, enrich the memory, or correct the knowledge.

Threshold misses require investigation; recalibration is not a guaranteed repair. Missing features may require additional telemetry. Wrong context can come from inaccurate documents, a bad mapping, query construction or ranking. Review the evidence before deciding which component to change.

The three strikes rule

Three similar routine misses trigger a tuning review, while a severe availability failure gets immediate investigation. Reviewers approve the correction; the count does not trigger an automatic production change. Recalibration itself does not roll back a harmful update.

Replay, Shadow, Promote

A candidate is evaluated on historical and live evidence before it is allowed to affect notifications.

Review triggercandidate change Offline replaymonths of labelled rows Shadow scoretwo weeks, silenced Acceptancegates pass? Promotetakes the pager fails replay: never shipsfails gates: back to the drawing board
The promotion path for any new feature, weight change or corpus change

Offline replay

Replay a candidate only against features and outcomes actually retained. A new column cannot reconstruct missing historical measurements. Use later, held-out periods and independent incident labels where available; count both missed incidents and additional pages.

Shadow scoring

A candidate runs without paging while its decisions are compared with the active version. The evaluation period must contain enough relevant incidents rather than simply reach a fixed number of days. Promotion requires reviewed results against explicit criteria, including missed incidents as well as precision and alert volume.

Locked evaluation thresholds

Version evaluation criteria before testing and retain a recoverable active version. Specify who can promote or roll back a candidate. Recording the pre-update model error alone is not an acceptance test or an automatic rollback mechanism.

Acceptance Gates

Retrieval review considers both freshness and usefulness. Neither freshness nor changed context alone proves that a candidate is better.

Gate one: freshness

Does the retrieval surface at least one passage verified within a set window? If every passage attached to a page is old, the knowledge behind the decision is suspect even if the decision was right.

Gate two: usefulness

Did the selected context help the investigation? Changed documents or a changed prediction do not establish improvement without reviewed outcomes.

Each comparison retains the old and new passage identifiers, revisions, scores and engineer relevance verdicts. Identical passages can still be useful; different passages can be worse. Numeric prediction and retrieval quality are evaluated independently.

Measuring the retrieval gap

A cosine gap between average passage vectors can describe a change in context. Computing it requires the vectors or an additional database calculation; query-to-passage distances alone are insufficient. Compare vectors only within the same representation version, and handle empty results or zero means explicitly. The example threshold below is not validated.

retrieval gap = 1 − cosine(average of old top three, average of new top three)     illustrative review flag: gap above 0.15

Seasonality and Richer Features

Potential improvements that need collected evidence and evaluation.

Seasonality beyond the week

A weekly average summarizes recent history; it does not by itself learn calendar-aware seasonality. Day of month or fiscal period could become additional features after collection and evaluation. Extra fields need schema, model and resource changes. Their benefit and overhead must be measured rather than assumed.

Richer inputs

Today the predictor reads numeric metrics only. Query level signals, such as which statements were running when replication lag spiked, would sharpen the early warning further. The challenge is doing that in AWK without bloating the forward pass, so any new input goes through the same replay and shadow path before it is trusted.

Adding a feature, step by step

StepAction
1The feature logger writes one more field in every row
2The shared history table gains one more column
3The predictor input widens by one column with its own starting weight
4Replay against labelled history, then shadow on live traffic
5Promote only after reviewed prediction-quality results; evaluate retrieval separately when it changes

Production Guardrails

This is production, so every intelligent part of the system is deliberately conservative.

GuardrailWhat it prevents
Monitoring queries run inside read only transactions with statement, lock and idle timeoutsThe agent can never change data or hold up the workload
Learning failures never stop monitoringA broken model falls back to plain threshold alerting
Adaptive thresholds only tightenLearning can never hide a real problem
Predictor weights are clipped and normalised with a small learning rateNo single bad week can distort the model
The noise gate fails open and never touches critical or availability alertsSuppression can only remove predictable noise
Vector retrieval remains advisoryKeep authorization separate from retrieved text; misleading advice still creates operational risk
Corrections to knowledge stay manualA person always makes the final call on what the agent believes
Credentials come only from protected password files, and secrets are redacted from logsNothing sensitive is hardcoded or leaked
State files are written atomicallyA crash mid write cannot corrupt memory
Only the node holding the virtual address runs the main cycleOne voice for the cluster, no duplicate pages

Questions and Answers

Questions a database engineer, reviewer or operator might ask, with the practical reasoning behind each answer.

These questions explain the operating model, the stored evidence and the boundaries between retrieval, prediction and human judgement.

Does the agent keep persistent memory of incidents, or is it stateless per run?
Metric baselines, feature history and learned weights persist between runs. Approved incident reviews also enter the passage index with their source and revision. Numeric learning history and document-retrieval memory are separate stores serving different purposes.
What happens to the learning after a failover?
Shared PostgreSQL history supports restoration of local state. Recovery depends on retained data, database connectivity and replication progress; it is not an unconditional one-cycle guarantee.
Can the model see across nodes and services?
The main cycle collects cluster observations, while PostgreSQL stores numeric history and indexed incident passages. This makes evidence available across runs and nodes, subject to access controls. Establishing cross-service causes still requires aligned timestamps and observations from the relevant services.
Where is the remaining friction?
Independent outcome labels, seasonal coverage, incomplete incident reviews and vocabulary gaps still need attention. Persistent storage preserves available evidence; it cannot create missing observations or guarantee a relevant match.
How is the feedback loop closed?
The numeric learner uses later monitoring status as a proxy label. Engineers separately review page correctness and passage usefulness, linked to the event and retrieved revisions. Those verdicts support evaluation and approved changes. Unreviewed pages remain unknown, not negative examples.
How can the agent reason without a language model?
The reasoning combines monitoring history, previous incident reviews, log evidence and runbooks. Known alert keys select deterministic guidance. The same alert's symptoms also become a query vector that retrieves related incident and runbook passages from PostgreSQL. The report brings together matched evidence, source revisions and a chronological incident view for the engineer to assess.
How are the documents embedded and ranked?
The indexer lowercases and tokenizes each approved passage, computes TF-IDF weights using a saved vocabulary and IDF snapshot, and normalizes the coordinates. PostgreSQL stores the vector with the original text and revision. At alert time, the same representation produces the query vector; pgvector's cosine-distance operator ranks compatible stored passages. The worked examples show the exact numbers and returned rows.
How do you know if a retrieved passage is helpful, misleading or outdated?
The retrieval record preserves the returned revision and score. The reviewing engineer checks relevance, version compatibility and operational accuracy, then records helpfulness. Age alone does not establish correctness; recurring failures prompt investigation of both source quality and selection.
What happens when a runbook is revised?
The indexer detects changed content and regenerates passages for the approved revision. New rows become active atomically, and old revisions remain available for audit. If the vocabulary or IDF snapshot changes, the corpus is reindexed under a new representation version.
How do you catch false positives and silent misses?
Incident review compares alerts with independently observed impact and tracks precision, missed incidents and lead time. Passage usefulness is measured separately. A correct page can carry unhelpful context, and a relevant runbook does not make an incorrect page valid.
How do you decide between tuning thresholds, adding features or fixing the corpus?
Check the evidence path first: telemetry, routing, thresholds, labels, document accuracy and selection. Different failures need different corrections. Do not wait for repeated misses before investigating a severe availability failure.
How is a new feature validated without spiking false positives?
Held-out replay is followed by non-paging shadow evaluation, using only retained observations. Reviewers compare missed incidents, precision and alert volume before promotion. Retrieval changes also require passage relevance and revision-validity checks.
Do you track whether retrieval actually changed?
The comparison records old and new passage identifiers, revisions, scores and relevance verdicts. A cosine gap identifies changed context, but only outcome review establishes whether that change helped.

Design boundaries

Is this a large language model built in a shell?
No. The numeric predictor combines fixed time-window averages with four learned metric weights. The retrieval layer compares document and query vectors. Neither generates language or uses learned query-key attention. Reasoning remains a traceable combination of measurements, rules and retrieved evidence.
What is the difference between learning memory and retrieval memory?
Learning memory stores measurements, proxy outcome labels, baselines and weights. Retrieval memory stores approved passage text, vectors and source revisions. Retrieving an incident review does not train the numeric predictor, and a shared database does not by itself establish cross-service causality.
Does a shared database remove every cluster blind spot?
No. Shared storage helps preserve observations, but the predictor must actually read aligned observations from the relevant sources. Clock differences, stale replicas and missing service events still matter. The main monitoring cycle is gated by virtual address ownership. History restoration is not the same as continuous analysis across services.
Can I trust a displayed seventy percent risk as a probability?
Not without calibration. The predictor turns a weighted risk score into three percentage outputs through fixed arithmetic. To call those calibrated probabilities, compare predicted risk bands with observed incident frequency on unseen data. Likewise, an early warning message is not proof of a measured lead time.
What if the monitoring labels are wrong?
The later monitoring status supplies the current training labels, so existing threshold mistakes can be learned again. Engineer verdicts should be separate evidence. An unreviewed page is unknown, not a negative example. A confirmed false alarm is a useful negative label. Keep these states distinct.
Does recalibration automatically reject a bad update?
Recalibration computes candidate weights; it does not establish that they are better. The separate promotion process evaluates the candidate against the active version and retains a recoverable previous version. Recording a pre-update error is not a substitute for that comparison.
Can I replay a feature that was never collected?
Only if trustworthy historical sources let me reconstruct it. Adding a column cannot create old observations. Otherwise I collect the feature without paging first. Evaluation should use later time periods that were not used for tuning and should separate incidents from repeated pages about the same incident.
What makes a retrieved passage useful rather than merely similar?
A useful passage matches the observed symptom, the component version and the action under consideration. An engineer then confirms whether it helped the diagnosis. A high similarity score alone cannot establish correctness. Review whether retrieval improved the investigation separately from whether the numeric predictor was right.
Are prompts or tokens getting older?
The evidence ages, not individual tokens. In the retrieval design, the query is symptom text rather than a prompt to a language model. Track when a passage was written, when it was verified, which software it applies to and whether another revision supersedes it. A newly edited date alone does not prove accuracy.
Does a checksum detect an outdated recommendation?
No. It detects changed bytes. A document can remain unchanged while the database version or operating procedure changes underneath it. Version compatibility and owner review must accompany change detection. Preserve the exact revision used for an older incident so later review remains reproducible.
Is a cosine gap enough to prove that retrieval improved?
No. It measures change, not usefulness. A different passage can be worse. Compare relevance judgements, citation validity and investigation outcomes as well as document overlap. Similarity scores between each passage and the query are not enough to compute the distance between the old and new passage vectors. That requires the vectors or additional distance calculations.
Can a local encoder simply replace the current representation?
It may fit the local execution constraint, but it still needs security approval and resource testing. A different vector dimension can require schema and index changes. Rebuild the corpus and query vectors with the same model version and compare both approaches on held out incident queries before switching.
Should I wait for three misses before fixing anything?
Repeated examples help avoid reacting to noise, but a severe availability or safety failure should be investigated immediately. Treat three similar misses as a review convention for routine tuning, not a rule that delays urgent action. Also check missing telemetry, units and routing before changing thresholds.
How do I know the pager is quieter for the right reason?
Track precision alongside missed incident rate, warning lead time and alert volume. A system can achieve perfect precision by almost never paging. Preserve critical alerts and compare candidates on the same incidents, with uncertainty reported when the sample is small.
Does advisory retrieval eliminate production risk?
It limits automatic consequences, but a misleading suggestion can still influence an engineer. Show the source, version and uncertainty and keep human authorization for consequential changes. The deployment also contains failover automation, which must be reviewed independently of the retrieval path.
What should happen when there is not enough evidence?
Make the gap visible. Missing history should keep optional prediction inactive rather than imply health. No suitable runbook should produce an honest absence of context rather than a forced match. Continue the deterministic checks and escalate uncertainty when the operational consequence warrants it.