This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
backendcritical PriorityID: pg17-streaming-vacuum-freeze-horizon-management

Postgres 17 Streaming Vacuum & Proactive XID Horizon Management

Enforces strict Transaction ID (XID) horizon tracking, adaptive per-table freeze limits, and Postgres 17 radix-tree vacuum buffer controls for high-throughput append-only workloads. Eliminates catastrophic stop-the-world anti-wraparound vacuum spikes by decoupling freeze cycles from generic autovacuum defaults and utilizing streaming memory management.

Prohibited Anti-Pattern: Default Autovacuum Configuration on Multi-Terabyte Append Tables Causing Emergency Anti-Wraparound I/O Saturation

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Postgres 17 Streaming Vacuum & Proactive XID Horizon Management - Enforces strict Transaction ID (XID) horizon tracking, adaptive per-table freeze limits, and Postgres 17 radix-tree vacuum buffer controls for high-throughput append-only workloads. Eliminates catastrophic stop-the-world anti-wraparound vacuum spikes by decoupling freeze cycles from generic autovacuum defaults and utilizing streaming memory management.
globs: src/database/**/*.ts, src/infrastructure/db/**/*.ts, migrations/**/*.sql, src/jobs/maintenance/**/*.ts
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/pg17-streaming-vacuum-freeze-horizon-management"
---

# Postgres 17 Streaming Vacuum & Proactive XID Horizon Management

> **Severity**: CRITICAL | **Category**: backend
> **Anti-Pattern Warning**: Default Autovacuum Configuration on Multi-Terabyte Append Tables Causing Emergency Anti-Wraparound I/O Saturation

## System Constraints
You are a Principal Database Reliability Engineer and Distributed Systems Architect enforcing strict Postgres 17 Vacuum and Transaction ID (XID) Horizon safety standards. In high-velocity, multi-terabyte append architectures, global autovacuum defaults inevitably trigger emergency anti-wraparound vacuum locks and catastrophic I/O saturation. Mandate Postgres 17 radix-tree TidStore utilization via vacuum_buffer_usage_limit, fine-grained table storage parameters (autovacuum_freeze_max_age, autovacuum_vacuum_insert_scale_factor), and synthetic continuous freeze batching. Prevent idle-in-transaction connections from blocking the global XID horizon.

## Strict Guidelines
- Engineers MUST ALWAYS configure table-level storage parameters for high-write/append-only tables with tuned autovacuum_vacuum_insert_threshold and autovacuum_vacuum_insert_scale_factor to prevent dead tuple buildup in Postgres 17.
- Engineers MUST ALWAYS leverage Postgres 17's vacuum_buffer_usage_limit on memory-intensive tables to prevent vacuum operations from thrashing shared_buffers and saturating disk read queues.
- Engineers MUST NOT rely on instance-wide autovacuum_freeze_max_age defaults for tables growing by more than 100M rows per day; freeze horizons must be proactively scheduled in small, non-blocking increments.
- Services MUST monitor age(relfrozenxid) and age(datfrozenxid) continuously, throwing actionable, tiered alerts when table XID age reaches 50% of autovacuum_freeze_max_age.
- Components NEVER allow long-running application transactions, stale replication slots, or unhandled prepared transactions (pg_prepared_xacts) to hold back datfrozenxid horizon progression beyond 15 minutes.

## Bad vs Good Implementations
### Postgres 17 Append-Only Storage Invariants & XID Horizon Telemetry Worker

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Default storage parameters omit insert vacuuming and custom freeze horizons. When the table exceeds millions of writes, vacuum_freeze_min_age defaults force delayed massive page re-writes. Furthermore, failure to monitor age(c.relfrozenxid) risks triggering fail-safe anti-wraparound vacuuming (autovacuum_freeze_max_age), causing extreme I/O spikes and table read starvation.
```typescript
import { Pool } from 'pg';

export async function setupTelemetryTable(pool: Pool) {
  // Anti-Pattern: Generic table creation with default autovacuum settings.
  // On high-throughput append workloads (>50k writes/sec), freeze horizon drifts
  // unmonitored until PostgreSQL forces an unthrottled anti-wraparound vacuum.
  await pool.query(`
    CREATE TABLE IF NOT EXISTS audit_events (
      id UUID PRIMARY KEY,
      payload JSONB NOT NULL,
      created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
    );
  `);
}

export async function monitorDatabase(pool: Pool) {
  // Anti-Pattern: Does not check transaction horizon age or stale locks
  const res = await pool.query('SELECT count(*) FROM audit_events');
  console.log(`Current rows: ${res.rows[0].count}`);
}
```

#### Production Standard (Correct)
> **Standard**: Configures Postgres 17 table storage options specifically for multi-terabyte append workloads: sets vacuum_buffer_usage_limit to 256MB (leveraging PG17's enhanced radix-tree TidStore vacuum engine), optimizes insert vacuum frequency, and lowers autovacuum_freeze_min_age. Implements strict horizon monitoring on age(c.relfrozenxid) to fail fast well before the 200M transaction emergency wrap-around freeze threshold.
```typescript
import { Pool } from 'pg';

export async function configurePg17AppendTable(pool: Pool): Promise<void> {
  // Postgres 17 Invariant: Apply aggressive insert vacuum thresholds,
  // explicit radix-tree buffer allocation, and continuous lower freeze ceilings.
  await pool.query(`
    CREATE TABLE IF NOT EXISTS audit_events (
      id UUID NOT NULL,
      payload JSONB NOT NULL,
      created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
    ) PARTITION BY RANGE (created_at);

    ALTER TABLE audit_events SET (
      autovacuum_vacuum_insert_threshold = 50000,
      autovacuum_vacuum_insert_scale_factor = 0.005,
      autovacuum_freeze_min_age = 10000000,
      autovacuum_freeze_table_age = 50000000,
      autovacuum_vacuum_cost_limit = 2000,
      autovacuum_vacuum_cost_delay = 2,
      vacuum_buffer_usage_limit = '256MB'
    );
  `);
}

interface HorizonMetrics {
  relname: string;
  txAge: number;
  percentToEmergencyFreeze: number;
}

export async function assertXidHorizonHealth(pool: Pool): Promise<void> {
  const EMERGENCY_FREEZE_LIMIT = 200_000_000;
  const WARNING_THRESHOLD_PERCENT = 50;

  const { rows } = await pool.query<HorizonMetrics>(`
    SELECT 
      c.relname,
      age(c.relfrozenxid) AS "txAge",
      ROUND((age(c.relfrozenxid)::numeric / $1::numeric) * 100, 2)::float AS "percentToEmergencyFreeze"
    FROM pg_class c
    JOIN pg_namespace n ON n.oid = c.relnamespace
    WHERE c.relkind IN ('r', 'm')
      AND n.nspname NOT IN ('pg_catalog', 'information_schema')
    ORDER BY age(c.relfrozenxid) DESC
    LIMIT 10;
  `, [EMERGENCY_FREEZE_LIMIT]);

  for (const table of rows) {
    if (table.percentToEmergencyFreeze >= WARNING_THRESHOLD_PERCENT) {
      throw new Error(
        `[CRITICAL_XID_DRIFT] Table ${table.relname} at ${table.percentToEmergencyFreeze}% ` +
        `of freeze max age (txAge: ${table.txAge}). Proactive freeze required.`
      );
    }
  }
}
```

Architectural Specification & Invariant Rationale

Architectural Invariant Design: Postgres 17 Streaming Vacuum & Proactive XID Horizon Management

Postgres 17 Streaming Vacuum & Proactive XID Horizon Management defines an industrial-grade behavioral standard for backend engineering. Enforces strict Transaction ID (XID) horizon tracking, adaptive per-table freeze limits, and Postgres 17 radix-tree vacuum buffer controls for high-throughput append-only workloads. Eliminates catastrophic stop-the-world anti-wraparound vacuum spikes by decoupling freeze cycles from generic autovacuum defaults and utilizing streaming memory management. Modern software architectures require strict adherence to deterministic patterns to guarantee high availability, maintainability, and zero security vulnerabilities.

Framework Paradigm Shift & Drift MechanicsLLMs are trained on millions of open-source repositories containing outdated code, legacy idioms, and unpatched antipatterns. When coding assistants generate implementations for this stack, they default to common statistical tokens: Default Autovacuum Configuration on Multi-Terabyte Append Tables Causing Emergency Anti-Wraparound I/O Saturation Without an explicit system instruction file, developers spend hours debugging silent failures.
Failure Modes & Production Blast Radius

Hazard Analysis: What Breaks Without This Rule

The following failure modes have been cataloged from hundreds of hours of production code reviews where AI assistants produced non-compliant implementations:

Failure ModeAI Symptom (The Anti-Pattern)SeverityProduction Impact & Remedy
AI Hallucination & Deprecation DriftDefault Autovacuum Configuration on Multi-Terabyte Append Tables Causing Emergency Anti-Wraparound I/O SaturationCritical
Violating this industrial standard introduces regression bugs, security risks, and unexpected runtime failures in production.
Enforce explicit behavioral system directives across all AI coding assistants in your repository.
Silent Architecture InconsistencyAI assistants produce mixed paradigms across files, creating fragmented codebase conventions.Medium
Increases cognitive load during code reviews and leads to maintenance debt across engineering teams.
Pin project conventions in .cursor/rules, CLAUDE.md, and AGENTS.md so all team agents follow identical guardrails.
Architectural Directives in Detail

Step-by-Step Production Directives

Each rule constraint below is injected into the AI agent's system prompt to establish deterministic boundaries:

1

Engineers MUST ALWAYS configure table-level storage parameters for high-write/append-only tables with tuned autovacuum_vacuum_insert_threshold and autovacuum_vacuum_insert_scale_factor to prevent dead tuple buildup in Postgres 17.

Engineers MUST ALWAYS configure table-level storage parameters for high-write/append-only tables with tuned autovacuum_vacuum_insert_threshold and autovacuum_vacuum_insert_scale_factor to prevent dead tuple buildup in Postgres 17.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
2

Engineers MUST ALWAYS leverage Postgres 17's vacuum_buffer_usage_limit on memory-intensive tables to prevent vacuum operations from thrashing shared_buffers and saturating disk read queues.

Engineers MUST ALWAYS leverage Postgres 17's vacuum_buffer_usage_limit on memory-intensive tables to prevent vacuum operations from thrashing shared_buffers and saturating disk read queues.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
3

Engineers MUST NOT rely on instance-wide autovacuum_freeze_max_age defaults for tables growing by more than 100M rows per day

Engineers MUST NOT rely on instance-wide autovacuum_freeze_max_age defaults for tables growing by more than 100M rows per day; freeze horizons must be proactively scheduled in small, non-blocking increments.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
4

Services MUST monitor age(relfrozenxid) and age(datfrozenxid) continuously, throwing actionable, tiered alerts when table XID age reaches 50% of autovacuum_freeze_max_age.

Services MUST monitor age(relfrozenxid) and age(datfrozenxid) continuously, throwing actionable, tiered alerts when table XID age reaches 50% of autovacuum_freeze_max_age.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
5

Components NEVER allow long-running application transactions, stale replication slots, or unhandled prepared transactions (pg_prepared_xacts) to hold back datfrozenxid horizon progression beyond 15 minutes.

Components NEVER allow long-running application transactions, stale replication slots, or unhandled prepared transactions (pg_prepared_xacts) to hold back datfrozenxid horizon progression beyond 15 minutes.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
Technical Questions & Answers

Frequently Asked Technical Questions

Common questions developers face when configuring AI coding assistants for this stack:

Q:Why is Postgres 17 Streaming Vacuum & Proactive XID Horizon Management critical for AI coding assistants?

Enforces strict Transaction ID (XID) horizon tracking, adaptive per-table freeze limits, and Postgres 17 radix-tree vacuum buffer controls for high-throughput append-only workloads. Eliminates catastrophic stop-the-world anti-wraparound vacuum spikes by decoupling freeze cycles from generic autovacuum defaults and utilizing streaming memory management. Without explicit behavioral boundaries, AI coding assistants (Cursor, Claude Code, Windsurf, Codex) rely on training data averages, which frequently produce deprecated, inefficient, or vulnerable code patterns.

Q:How does adopting this rule prevent AI hallucinations?

This rule explicitly declares what the AI must avoid (Default Autovacuum Configuration on Multi-Terabyte Append Tables Causing Emergency Anti-Wraparound I/O Saturation) and prescribes verified positive examples. Grounding the LLM with negative and positive pairs eliminates guesswork.

Q:Which AI coding environments are supported?

This specification is multi-platform compatible: Cursor (.cursor/rules/*.mdc & .cursorrules), Anthropic Claude Code (CLAUDE.md), Windsurf (.windsurfrules), Codex / Cline (AGENTS.md), and GitHub Copilot (.github/copilot-instructions.md).

Q:Can I combine this rule with other technology stacks?

Yes. Use the Interactive Stack Builder or download an Agent Pack to merge this rule with other frontend, backend, database, security, and DevOps rules without syntax collision.

Open Specification · CC BY 4.0·Free for Personal, Team & Commercial In-Repo Use

Citation & Open Source Attribution Guidelines

This specification is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0). You are completely free to adapt and share this rule in your workspace. If citing, including in public AI benchmark datasets, or redistributing, attribution to AgentRules.org is required.

1 Rule in Stack

Postgres