Schedule icon
Webhook icon
Query icon
Script icon
Docker icon
Set icon
If icon
SlackIncomingWebhook icon
Log icon
Loop icon
Fail icon
OutputValues icon

Audit PostgreSQL Table Bloat and Transaction ID Wraparound Autovacuum Headroom

Monitor PostgreSQL table dead tuple bloat and XID wraparound headroom, alert via Slack on autovacuum starvation, and run targeted VACUUM maintenance.

Categories
DataInfrastructure

How it works

PostgreSQL uses Multi-Version Concurrency Control (MVCC) to provide transactional isolation. When a row is updated or deleted, PostgreSQL writes a new tuple version and marks the existing tuple dead. Dead tuples consume disk space and page cache until reclaimed by VACUUM. Under heavy write traffic, long-running transactions, or misconfigured scale factors, the PostgreSQL autovacuum daemon can experience autovacuum starvation, leading to severe index degradation, sequential scan latency, and table bloat.

Simultaneously, PostgreSQL tracks transaction IDs (XIDs) as 32-bit integers. If age(datfrozenxid) approaches $2^{31}$ (2.14 billion transactions) without an aggressive anti-wraparound freeze, PostgreSQL enters an emergency read-only shutdown mode to prevent silent data corruption.

This blueprint provides an enterprise Day 2 operations sentinel that continuously monitors both table dead tuple bloat and cluster-wide XID wraparound headroom:

  1. Catalog Telemetry Extraction: Connects via native JDBC (io.kestra.plugin.jdbc.postgresql.Query) to probe pg_database for age(datfrozenxid) and calculate remaining headroom (2^31 - age(datfrozenxid)), and inspects pg_stat_user_tables to calculate exact dead tuple ratios (n_dead_tup / (n_live_tup + n_dead_tup)).
  2. Telemetry Evaluation & Classification: A Dockerized Python script evaluates catalog statistics against warning thresholds (bloat_ratio_threshold_pct, default 30%, and min_xid_headroom, default 200M XIDs). It sorts bloated tables by severity and selects the top candidate targets for maintenance.
  3. KV State Persistence: Persists a full JSON snapshot into Kestra's built-in Key-Value store (postgres_vacuum_sentinel_latest) for SLA reporting and historical trending.
  4. Wraparound Emergency Gate: If transaction headroom drops below 200 million transactions, the flow immediately fires high-priority Slack incident alerts and triggers workflow failure.
  5. Targeted VACUUM Maintenance: When tables suffer from autovacuum starvation, the flow executes sequential, bounded VACUUM ANALYZE operations during scheduled off-peak windows to reclaim dead storage and update query planner optimizer statistics without saturating cluster I/O.

What you get

  • Automated, non-invasive catalog inspection of dead tuple accumulation across user tables.
  • Early warning detection for Transaction ID wraparound exhaustion before PostgreSQL forces an emergency read-only shutdown.
  • Automated remediation via targeted VACUUM ANALYZE on bloated candidate tables during maintenance windows.
  • Bounded concurrency with customizable table limits (max_vacuum_tables) to prevent storage I/O spikes.
  • Full telemetry audit trails stored in Kestra KV store for long-term health tracking.
  • Rich Slack notifications with database diagnostics and vacuum execution summaries.

Who it's for

  • Database Administrators (DBAs) managing high-throughput PostgreSQL production clusters.
  • Site Reliability Engineers (SREs) safeguarding database storage capacity, read SLAs, and uptime.
  • Data Platform Engineers running batch ETL and CDC pipelines prone to burst dead tuple accumulation.

Why orchestrate this with Kestra

  • Native Catalog Inspection: Leverages io.kestra.plugin.jdbc.postgresql.Query to query internal PostgreSQL system views directly without deploying external daemon agents.
  • Safe Remediative Execution: Provides declarative flow control (io.kestra.plugin.core.flow.If and io.kestra.plugin.core.flow.Loop) with dry-run safety modes, preventing uncoordinated database load.
  • Centralized Auditability & KV Storage: Maintains execution logs, outputs, and JSON telemetry reports in Kestra's unified control plane.
  • Event-Driven & Scheduled Flexibility: Supports both cron-based scheduled off-peak sweeps and webhook triggers for ad-hoc post-ingestion validation.

Prerequisites

  • PostgreSQL cluster (version 12 or newer) reachable from Kestra worker instances.
  • Dedicated database user account with pg_read_all_stats role (or superuser) and VACUUM permissions on target tables.
  • Network connectivity from Kestra workers to the database host and Slack webhook endpoint.

Secrets

  • POSTGRES_PASSWORD: Password for the PostgreSQL administrative or maintenance user.
  • SLACK_WEBHOOK_URL: Slack Incoming Webhook URL to deliver operational alerts and maintenance notices.
  • POSTGRES_SENTINEL_WEBHOOK_KEY: Secret authentication token for the inbound Kestra Webhook trigger.

Quick start

  1. Configure the required secrets (POSTGRES_PASSWORD, SLACK_WEBHOOK_URL, POSTGRES_SENTINEL_WEBHOOK_KEY) in your Kestra namespace.
  2. Deploy this blueprint flow to your Kestra instance under namespace company.database.
  3. Run a manual test execution with dry_run: true to inspect your cluster's current bloat and wraparound headroom.
  4. Enable the off_peak_maintenance_window schedule trigger to run automated daily maintenance at 02:00 UTC.

How to extend

  • Add PagerDuty or Opsgenie notifications via io.kestra.plugin.pagerduty for P1 escalation when wraparound headroom drops below 50 million XIDs.
  • Incorporate table size queries using pg_total_relation_size() to calculate estimated gigabytes of reclaimable bloat.
  • Chain this flow as an upstream dependency gate in Kestra ETL pipelines to ensure databases are vacuumed before large batch loads begin.
  • Extend candidate vacuuming to support VACUUM (PARALLEL 4) on PostgreSQL 13+ instances with multi-core worker availability.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.