This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
backendcritical PriorityID: postgres-17-async-io-cdc-replication-guardrails

Postgres 17 Asynchronous I/O Tuning & CDC Logical Slot WAL Guardrails

Configures Postgres 17 native async I/O parameters for high-throughput vectorized operations while enforcing strict WAL-retention ceilings via max_slot_wal_keep_size on CDC replication streams. Prevents cluster-wide disk exhaustion outages caused by stalled downstream CDC consumers and ensures deterministic streaming reads across high-volume pipelines.

Prohibited Anti-Pattern: Uncapped Logical Replication Slots and Unbounded CDC Lag Exhausting Node Storage

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Postgres 17 Asynchronous I/O Tuning & CDC Logical Slot WAL Guardrails - Configures Postgres 17 native async I/O parameters for high-throughput vectorized operations while enforcing strict WAL-retention ceilings via max_slot_wal_keep_size on CDC replication streams. Prevents cluster-wide disk exhaustion outages caused by stalled downstream CDC consumers and ensures deterministic streaming reads across high-volume pipelines.
globs: src/**/*.ts, src/**/*.js, infra/**/*.tf, infra/**/*.sql, docker-compose*.yml, helm/**/*.yaml
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/postgres-17-async-io-cdc-replication-guardrails"
---

# Postgres 17 Asynchronous I/O Tuning & CDC Logical Slot WAL Guardrails

> **Severity**: CRITICAL | **Category**: backend
> **Anti-Pattern Warning**: Uncapped Logical Replication Slots and Unbounded CDC Lag Exhausting Node Storage

## System Constraints
You are a Principal Database Architect and Infrastructure Engineer enforcing Postgres 17 Asynchronous I/O and CDC Logical Replication standards. Mandate strict limits on Write-Ahead Log (WAL) retention to prevent catastrophic storage saturation, optimize streaming read concurrency for high-throughput pipelines, and ensure CDC consumers reliably acknowledge Log Sequence Numbers (LSNs) with robust fallback handling for invalidated slots.

## Strict Guidelines
- Engineers MUST ALWAYS configure `max_slot_wal_keep_size` to a deterministic non-negative limit (e.g., 32768MB - 65536MB) on any Postgres instance utilizing logical replication slots.
- Engineers MUST NOT allow logical replication consumers to ingest records without periodically acknowledging the flush LSN (`pg_replication_slot_advance` or protocol-level Standby Status Updates), bounded by an interval not exceeding 5 seconds.
- Services MUST monitor `pg_replication_slots` for `wal_status = 'lost'` or `wal_status = 'extended'` and immediately fail fast or alert before disk volume utilization breaches 85%.
- Code SHOULD optimize Postgres 17 I/O concurrency settings (`effective_io_concurrency`, `maintenance_io_concurrency`, and `io_combine_limit`) to match NVMe-backed queue depths for vectorized bulk reads.
- Components NEVER execute long-running transactions (such as analytical queries or unindexed batch migrations) on the primary cluster while CDC logical decoding is active, as this blocks WAL recycling and bloats `pg_catalog`.

## Bad vs Good Implementations
### CDC Consumer LSN Acknowledgment and WAL Retention Guard

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Failing to set max_slot_wal_keep_size and consuming WAL changes without transactional LSN advancement causes Postgres to pin WAL files indefinitely. If processing stalls, WAL fills the disk, terminating the cluster.
```typescript
import { Client } from 'pg';

export async function runUnsafeCdcConsumer(client: Client) {
  // Anti-Pattern: Consuming logical replication stream without tracking confirmed flush LSN
  // and without checking slot retention or storage lag limits.
  const stream = await client.query(
    `SELECT lsn, data FROM pg_logical_slot_get_changes('debezium_cdc_slot', NULL, NULL)`
  );

  for (const row of stream.rows) {
    // Slow downstream processing with no flush confirmation back to the WAL engine
    await processExternalMessage(row.data);
  }
  // If this service crashes or hangs, the replication slot retains 100% of generated WAL indefinitely,
  // inevitably filling the entire disk partition and bringing down the Postgres primary.
}
```

#### Production Standard (Correct)
> **Standard**: Enforces preflight checks for finite `max_slot_wal_keep_size`, consumes changes in bounded batches, explicitly advances the slot's acknowledged LSN, and detects invalidated slots (`wal_status = 'lost'`) before disk exhaustion.
```typescript
import { Client } from 'pg';

interface ReplicationLagStatus {
  slot_name: string;
  wal_status: 'normal' | 'extended' | 'lost' | 'unreserved';
  retained_bytes: number;
}

export async function runProductionCdcConsumer(client: Client): Promise<void> {
  // Invariant: Verify max_slot_wal_keep_size is capped to prevent catastrophic disk saturation
  const configCheck = await client.query<{ setting: string }>(
    `SELECT setting FROM pg_settings WHERE name = 'max_slot_wal_keep_size'`
  );
  const maxWalMb = parseInt(configCheck.rows[0]?.setting ?? '-1', 10);
  if (maxWalMb <= 0) {
    throw new Error('CRITICAL: max_slot_wal_keep_size must be set to a positive bound before starting CDC');
  }

  const BATCH_SIZE = 500;
  // Invariant: Pull bounded chunks using explicit end_lsn and acknowledge flush LSN
  const result = await client.query(
    `SELECT lsn, data FROM pg_logical_slot_get_changes('debezium_cdc_slot', NULL, $1)`, 
    [BATCH_SIZE]
  );

  if (result.rows.length === 0) return;

  let lastCommittedLsn: string | null = null;
  for (const row of result.rows) {
    await processExternalMessage(row.data);
    lastCommittedLsn = row.lsn;
  }

  // Acknowledge flush LSN to permit immediate WAL segment recycling
  if (lastCommittedLsn) {
    await client.query(
      `SELECT pg_replication_slot_advance('debezium_cdc_slot', $1::pg_lsn)`,
      [lastCommittedLsn]
    );
  }

  // Invariant: Fail fast if slot status drops out of 'normal'
  const slotStatus = await client.query<ReplicationLagStatus>(
    `SELECT slot_name, wal_status, pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)::bigint AS retained_bytes
     FROM pg_replication_slots WHERE slot_name = 'debezium_cdc_slot'`
  );
  
  if (slotStatus.rows[0]?.wal_status === 'lost') {
    throw new Error('CRITICAL: Replication slot invalidated due to max_slot_wal_keep_size exceeded. Resync required.');
  }
}
```

Recommended MCP Servers (mcp-serverlist.com)

Equip agent with system tools to verify code for this stack.

Recommended Agent Skills (askills.dev)

Ready-to-use executable skill functions tailored to this stack.

Architectural Specification & Invariant Rationale

Architectural Invariant Design: Postgres 17 Asynchronous I/O Tuning & CDC Logical Slot WAL Guardrails

Postgres 17 Asynchronous I/O Tuning & CDC Logical Slot WAL Guardrails defines an industrial-grade behavioral standard for backend engineering. Configures Postgres 17 native async I/O parameters for high-throughput vectorized operations while enforcing strict WAL-retention ceilings via max_slot_wal_keep_size on CDC replication streams. Prevents cluster-wide disk exhaustion outages caused by stalled downstream CDC consumers and ensures deterministic streaming reads across high-volume pipelines. 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: Uncapped Logical Replication Slots and Unbounded CDC Lag Exhausting Node Storage 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 DriftUncapped Logical Replication Slots and Unbounded CDC Lag Exhausting Node StorageCritical
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 `max_slot_wal_keep_size` to a deterministic non-negative limit (e.g., 32768MB - 65536MB) on any Postgres instance utilizing logical replication slots.

Engineers MUST ALWAYS configure `max_slot_wal_keep_size` to a deterministic non-negative limit (e.g., 32768MB - 65536MB) on any Postgres instance utilizing logical replication slots.

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 NOT allow logical replication consumers to ingest records without periodically acknowledging the flush LSN (`pg_replication_slot_advance` or protocol-level Standby Status Updates), bounded by an interval not exceeding 5 seconds.

Engineers MUST NOT allow logical replication consumers to ingest records without periodically acknowledging the flush LSN (`pg_replication_slot_advance` or protocol-level Standby Status Updates), bounded by an interval not exceeding 5 seconds.

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

Services MUST monitor `pg_replication_slots` for `wal_status = 'lost'` or `wal_status = 'extended'` and immediately fail fast or alert before disk volume utilization breaches 85%.

Services MUST monitor `pg_replication_slots` for `wal_status = 'lost'` or `wal_status = 'extended'` and immediately fail fast or alert before disk volume utilization breaches 85%.

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

Code SHOULD optimize Postgres 17 I/O concurrency settings (`effective_io_concurrency`, `maintenance_io_concurrency`, and `io_combine_limit`) to match NVMe-backed queue depths for vectorized bulk reads.

Code SHOULD optimize Postgres 17 I/O concurrency settings (`effective_io_concurrency`, `maintenance_io_concurrency`, and `io_combine_limit`) to match NVMe-backed queue depths for vectorized bulk reads.

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 execute long-running transactions (such as analytical queries or unindexed batch migrations) on the primary cluster while CDC logical decoding is active, as this blocks WAL recycling and bloats `pg_catalog`.

Components NEVER execute long-running transactions (such as analytical queries or unindexed batch migrations) on the primary cluster while CDC logical decoding is active, as this blocks WAL recycling and bloats `pg_catalog`.

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 Asynchronous I/O Tuning & CDC Logical Slot WAL Guardrails critical for AI coding assistants?

Configures Postgres 17 native async I/O parameters for high-throughput vectorized operations while enforcing strict WAL-retention ceilings via max_slot_wal_keep_size on CDC replication streams. Prevents cluster-wide disk exhaustion outages caused by stalled downstream CDC consumers and ensures deterministic streaming reads across high-volume pipelines. 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 (Uncapped Logical Replication Slots and Unbounded CDC Lag Exhausting Node Storage) 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