Back to .md Directory

Alert Escalation & Query Regression Detection

Defines severity tiers, escalation chains, slow query thresholds, and regression detection rules for a PostgreSQL-backed application.

May 2, 2026
0 downloads
2 views
ai workflow guardrails
View source

What this file does

Defines severity tiers, escalation chains, slow query thresholds, and regression detection rules for a PostgreSQL-backed application.

When to use it

  • Setting up on-call rotation and alert routing
  • Adding automated query performance regression checks
  • Monitoring index drift and bloat in PostgreSQL
  • Integrating alerting with existing observability and incident response docs

Assumes this stack

PostgreSQLpg_stat_statementsSlackGitHub IssuesCI/CD

Alert Escalation & Query Regression Detection

Last updated: 2026-03-04 Status: Active Owner issue: #211 Dependencies: OBSERVABILITY.md (logging), LOG_SCHEMA.md (error codes), PERFORMANCE_GUARDRAILS.md (budgets) Machine-readable source of truth: monitoring/alerts.yml — validated by CI (.github/workflows/validate-alerts.yml)


1. Alert Escalation Policy

Severity Tiers

TierConditionDurationChannelResponse TimeEscalation
P0 — CriticalAny CRITICAL error code (LOG_SCHEMA.md)1 occurrencePage on-call immediately5 minAutomatic incident
P0 — CriticalMigration lock > 30s1 occurrencePage on-call5 minPrepare rollback
P1 — HighAPI P95 > 2000ms1 min sustainedPage on-call5 minTreat as incident
P1 — HighDatabase connections > 80% pool5 min sustainedSlack alert15 minInvestigate connection leaks
P2 — MediumAPI P95 > 1000ms3 min sustainedSlack alert30 min→ Page if no ack in 30 min
P2 — MediumSearch zero-result rate > 20%1 hour sustainedSlack alert4 hoursInvestigate query patterns
P2 — MediumProvenance conflicts > 50 unresolvedDaily checkSlack alert24 hoursAssign to data team
P3 — LowAPI P95 > 500ms5 min sustainedDashboard amber1 hour→ Slack if still amber after 1h
P3 — LowScoring version drift > 5% productsDaily checkDashboard amber24 hoursSchedule re-score batch
P3 — LowDisk usage > 80%Daily checkSlack alert24 hoursPlan cleanup or expansion

Escalation Chain

Dashboard amber (P3)
  ↓ (if unresolved after response time)
Slack #alerts channel (P2)
  ↓ (if unresolved after response time)
Page on-call engineer (P1/P0)
  ↓ (if unresolved in 30 min)
Incident declared → INCIDENT_RESPONSE.md playbook

On-Call Rules

  • Rotation: Weekly, starting Monday 09:00 CET
  • Response: Acknowledge within response time or auto-escalate
  • Handoff: Document open alerts in handoff notes at rotation boundary
  • Override: Any team member can self-assign an alert regardless of rotation

2. Slow Query Telemetry

Slow query monitoring uses report_slow_queries() from migration 20260222050000_query_performance_guardrails.sql.

Thresholds

CategoryMean Execution TimeAction
OK< 100msNo action
Warning100–500msLog, review weekly
Slow500ms–1sSlack alert, investigate within 24h
Critical> 1sPage on-call, investigate immediately

Existing Infrastructure

  • report_slow_queries(p_threshold_ms) — returns queries above threshold with category classification
  • check_plan_quality(p_query_text) — EXPLAIN ANALYZE with plan node flagging
  • Both restricted to service_role (SECURITY DEFINER)

3. Query Regression Detection

Architecture

pg_stat_statements
       │
       ▼
snapshot_query_performance()  ←── weekly cron / manual call
       │
       ▼
query_performance_snapshots   (historical data)
       │
       ▼
v_query_regressions           (compare current vs previous week)

Detection Rules

Regression LevelConditionAlert
OKCurrent mean ≤ previous mean × 1.3None
WARNINGCurrent mean > previous mean × 1.5Dashboard amber
CRITICALCurrent mean > previous mean × 2.0Slack alert

Retention

  • Keep weekly snapshots for 12 weeks (84 days)
  • After 12 weeks, aggregate to monthly summaries or delete
  • Estimated storage: ~50 rows/week × 12 weeks = ~600 rows max

4. Index Drift Monitoring

Detection Views

ViewPurposeAlert Condition
v_unused_indexesIndexes with zero or very few scansUNUSED index > 10MB
v_missing_indexesTables with excessive sequential scansNEEDS_INDEX status on large table
v_index_bloat_estimateIndex size vs table size ratioIndex > 2× table size

Review Cadence

  • Weekly: Review v_unused_indexes for zero-scan indexes
  • Weekly: Review v_missing_indexes for sequential scan patterns
  • Monthly: Review v_index_bloat_estimate for fragmentation
  • After migrations: Run all three views to verify index health

Action Matrix

FindingActionUrgency
Unused index (0 scans, > 10MB)Consider DROP INDEX after 4 weeks of inactivityLow
Rarely used index (< 10 scans)Monitor for 2 more weeks, then decideLow
Missing index (high seq scans)Create index, EXPLAIN ANALYZE to verifyMedium
Bloated index (> 2× table)REINDEX or DROP + CREATELow

5. Database Schema

Tables

  • query_performance_snapshots — Weekly snapshots of query performance metrics

Functions

  • snapshot_query_performance() — Captures current pg_stat_statements data into snapshots table (SECURITY DEFINER, service_role only)

Views

  • v_query_regressions — Compares current vs previous snapshot to detect performance regressions
  • v_unused_indexes — Identifies indexes with zero or very few scans
  • v_missing_indexes — Identifies tables with excessive sequential scans relative to index scans
  • v_index_bloat_estimate — Estimates index bloat by comparing index size to table size

6. Integration Points

SystemIntegration
LOG_SCHEMA.mdError codes: SEARCH_QUERY_002 (timeout), MIGRATION_LOCK_001 (lock)
OBSERVABILITY.mdStructured log format for alert events
PERFORMANCE_GUARDRAILS.mdQuery budget definitions, statement timeouts
INCIDENT_RESPONSE.mdEscalation leads to incident declaration
Admin Dashboard (#206)Views feed dashboard cards (future)

What's inside

6 sections: escalation policy table, query thresholds, regression rules, index drift views, schema objects, integration points

Change this for your project

  • Replace #211 with your own tracking issue number
  • Replace monitoring/alerts.yml with your alert definition path
  • Replace 20260222050000_query_performance_guardrails.sql with your migration filename
  • Replace service_role with your own restricted role name

Where it goes

Keep with your observability configuration. Describes what to track and alert on.

Worth borrowing

  • Escalation chain from dashboard amber to Slack to page to incident
  • Query regression detection comparing weekly snapshots with multiplicative thresholds
  • Index drift monitoring with action matrix and review cadence

Related Documents