This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
backendcritical PriorityID: postgres-17-logical-replication-slot-failover-lag-fencing

Postgres 17 Logical Replication Failover Slot Synchronization & Lag Fencing Invariants

Enforces explicit failover-enabled logical replication slots (failover = true) and strict lag-fencing orchestration during automated physical standby promotions in PostgreSQL 17. Guarantees that CDC consumers and downstream event streams never suffer unrecoverable LSN divergence or silent message loss across multi-region failovers.

Prohibited Anti-Pattern: Unfenced Standby Promotion with Desynchronized Logical Slots Leading to CDC Consumer Invalidation and Silent Data Divergence

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Postgres 17 Logical Replication Failover Slot Synchronization & Lag Fencing Invariants - Enforces explicit failover-enabled logical replication slots (failover = true) and strict lag-fencing orchestration during automated physical standby promotions in PostgreSQL 17. Guarantees that CDC consumers and downstream event streams never suffer unrecoverable LSN divergence or silent message loss across multi-region failovers.
globs: src/database/**/*.ts, src/replication/**/*.ts, src/cdc/**/*.ts, deploy/**/*.ts, infra/**/*.ts
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/postgres-17-logical-replication-slot-failover-lag-fencing"
---

# Postgres 17 Logical Replication Failover Slot Synchronization & Lag Fencing Invariants

> **Severity**: CRITICAL | **Category**: backend
> **Anti-Pattern Warning**: Unfenced Standby Promotion with Desynchronized Logical Slots Leading to CDC Consumer Invalidation and Silent Data Divergence

## System Constraints
You are a Principal Database Infrastructure Architect enforcing PostgreSQL 17 Logical Replication failover standards. Mandate that all logical replication slots used for CDC (Debezium, Kafka Connect, custom tailers) set failover = true, ensure the primary configures synchronized_standby_slots, and require orchestration code to fence downstream consumers, synchronize slots via pg_sync_replication_slots(), and assert zero lag before triggering pg_promote().

## Strict Guidelines
- Engineers MUST ALWAYS create logical replication slots with FAILOVER (true) in PostgreSQL 17 to permit standby slot persistence across promotions.
- Engineers MUST configure primary instances with 'synchronized_standby_slots' referencing the physical replication standby application_name to prevent the primary from advancing WAL past the standby's replay state.
- Promotion orchestrators MUST execute pg_sync_replication_slots() and verify synced = true and zero WAL lag (pg_wal_lsn_diff == 0) in pg_replication_slots before issuing pg_promote().
- Services MUST fence downstream CDC consumers (revoke credentials or pause consumer offset advancement) before promoting the standby to eliminate race conditions during LSN rewinds or failovers.
- Engineers MUST NOT rely on default pg_create_logical_replication_slot() without the FAILOVER parameter, as slots will not be preserved or synchronized to physical standbys in PG 17.
- Failover automation NEVER marks a standby promotion as healthy if any logical slot marked failover=true exhibits confirmed_flush_lsn divergence greater than the application's strict recovery point objective (RPO=0).

## Bad vs Good Implementations
### Postgres 17 Logical Slot Lag Fencing and Promotion Orchestrator

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Executing pg_promote() without invoking pg_sync_replication_slots() or checking pg_replication_slots.synced causes downstream CDC readers to lose track of confirmed_flush_lsn. In Postgres 17, non-failover slots or desynchronized failover slots lead to invalidated logical decoders, data loss, or inconsistent replay.
```typescript
import { Client } from 'pg';

// ANTI-PATTERN: Naive promotion without slot synchronization or lag fencing
export async function promoteStandbyUnsafe(standbyClient: Client): Promise<void> {
  // Triggers immediate promotion; logical replication slots on standby are un-synced or dropped,
  // causing CDC stream (Debezium/Kafka) to crash with unrecoverable LSN gaps or replay duplicates.
  await standbyClient.query('SELECT pg_promote(wait => true);');
}
```

#### Production Standard (Correct)
> **Standard**: Enforces PostgreSQL 17 native logical replication failover mechanisms. Calls pg_sync_replication_slots(), asserts slot.failover is true, verifies slot.synced is true, and confirms that WAL replay lag is exactly zero bytes before executing pg_promote(). This guarantees zero CDC message drop and prevents duplicate replay.
```typescript
import { Client } from 'pg';

export interface LogicalSlotSyncResult {
  slotName: string;
  synced: boolean;
  lagBytes: number;
}

// PRODUCTION INVARIANT: Fence CDC, synchronize failover slots, verify RPO=0, then promote
export async function promoteStandbySafe(
  standbyClient: Client,
  cdcSlotName: string,
  timeoutMs: number = 30000
): Promise<void> {
  const startTime = Date.now();

  // 1. Force explicit slot synchronization from the primary to this standby in Postgres 17
  await standbyClient.query('SELECT pg_sync_replication_slots();');

  // 2. Poll until the logical replication slot is synced and lag reaches 0
  let isReady = false;
  while (!isReady && (Date.now() - startTime) < timeoutMs) {
    const res = await standbyClient.query<{
      slot_name: string;
      synced: boolean;
      failover: boolean;
      lag_bytes: string;
    }>(
      `SELECT
         slot_name,
         synced,
         failover,
         pg_wal_lsn_diff(pg_last_wal_replay_lsn(), confirmed_flush_lsn)::text AS lag_bytes
       FROM pg_replication_slots
       WHERE slot_name = $1 AND slot_type = 'logical'`, 
      [cdcSlotName]
    );

    if (res.rows.length === 0) {
      throw new Error(`Logical slot ${cdcSlotName} does not exist on standby.`);
    }

    const slot = res.rows[0];
    if (!slot.failover) {
      throw new Error(`Slot ${cdcSlotName} is not configured with failover=true; cannot safely promote.`);
    }

    const lagBytes = BigInt(slot.lag_bytes ?? '0');
    if (slot.synced && lagBytes === 0n) {
      isReady = true;
    } else {
      await standbyClient.query('SELECT pg_sync_replication_slots();');
      await new Promise(resolve => setTimeout(resolve, 500));
    }
  }

  if (!isReady) {
    throw new Error(`Timeout waiting for logical slot ${cdcSlotName} to reach sync parity.`);
  }

  // 3. Perform atomic promotion once replication slot lag is strictly fenced
  const promotionResult = await standbyClient.query<{ pg_promote: boolean }>(
    'SELECT pg_promote(wait => true, wait_seconds => 60);'
  );

  if (!promotionResult.rows[0]?.pg_promote) {
    throw new Error('Promotion failed on standby instance.');
  }
}
```

Recommended MCP Servers (mcp-serverlist.com)

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

Architectural Specification & Invariant Rationale

Architectural Invariant Design: Postgres 17 Logical Replication Failover Slot Synchronization & Lag Fencing Invariants

Postgres 17 Logical Replication Failover Slot Synchronization & Lag Fencing Invariants defines an industrial-grade behavioral standard for backend engineering. Enforces explicit failover-enabled logical replication slots (failover = true) and strict lag-fencing orchestration during automated physical standby promotions in PostgreSQL 17. Guarantees that CDC consumers and downstream event streams never suffer unrecoverable LSN divergence or silent message loss across multi-region failovers. 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: Unfenced Standby Promotion with Desynchronized Logical Slots Leading to CDC Consumer Invalidation and Silent Data Divergence 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 DriftUnfenced Standby Promotion with Desynchronized Logical Slots Leading to CDC Consumer Invalidation and Silent Data DivergenceCritical
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 create logical replication slots with FAILOVER (true) in PostgreSQL 17 to permit standby slot persistence across promotions.

Engineers MUST ALWAYS create logical replication slots with FAILOVER (true) in PostgreSQL 17 to permit standby slot persistence across promotions.

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 configure primary instances with 'synchronized_standby_slots' referencing the physical replication standby application_name to prevent the primary from advancing WAL past the standby's replay state.

Engineers MUST configure primary instances with 'synchronized_standby_slots' referencing the physical replication standby application_name to prevent the primary from advancing WAL past the standby's replay state.

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

Promotion orchestrators MUST execute pg_sync_replication_slots() and verify synced = true and zero WAL lag (pg_wal_lsn_diff == 0) in pg_replication_slots before issuing pg_promote().

Promotion orchestrators MUST execute pg_sync_replication_slots() and verify synced = true and zero WAL lag (pg_wal_lsn_diff == 0) in pg_replication_slots before issuing pg_promote().

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 fence downstream CDC consumers (revoke credentials or pause consumer offset advancement) before promoting the standby to eliminate race conditions during LSN rewinds or failovers.

Services MUST fence downstream CDC consumers (revoke credentials or pause consumer offset advancement) before promoting the standby to eliminate race conditions during LSN rewinds or failovers.

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

Engineers MUST NOT rely on default pg_create_logical_replication_slot() without the FAILOVER parameter, as slots will not be preserved or synchronized to physical standbys in PG 17.

Engineers MUST NOT rely on default pg_create_logical_replication_slot() without the FAILOVER parameter, as slots will not be preserved or synchronized to physical standbys in PG 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.
6

Failover automation NEVER marks a standby promotion as healthy if any logical slot marked failover=true exhibits confirmed_flush_lsn divergence greater than the application's strict recovery point objective (RPO=0).

Failover automation NEVER marks a standby promotion as healthy if any logical slot marked failover=true exhibits confirmed_flush_lsn divergence greater than the application's strict recovery point objective (RPO=0).

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 Logical Replication Failover Slot Synchronization & Lag Fencing Invariants critical for AI coding assistants?

Enforces explicit failover-enabled logical replication slots (failover = true) and strict lag-fencing orchestration during automated physical standby promotions in PostgreSQL 17. Guarantees that CDC consumers and downstream event streams never suffer unrecoverable LSN divergence or silent message loss across multi-region failovers. 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 (Unfenced Standby Promotion with Desynchronized Logical Slots Leading to CDC Consumer Invalidation and Silent Data Divergence) 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