This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
backendcritical PriorityID: postgres-subtransaction-splintering-snapshot-quarantine

Postgres Subtransaction Splintering and Snapshot Metadata Quarantine Guardrail

Enforces strict limits against nested subtransactions and savepoint proliferation in PostgreSQL OLTP workloads. Uncontrolled savepoint chains overflow backend ProcArray subxid caches (exceeding the 64-entry inline ceiling), triggering global SubtransSLRULock contention, snapshot bloat, and accelerated transaction ID (XID) wraparound exhaustion. High-throughput database clients must decouple transient failure handling from database-level savepoints using application-tier idempotent retries.

Prohibited Anti-Pattern: Nested Savepoints and ORM Subtransaction Splintering Saturating PGPROC SubXID Caches and SLRU Locks

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Postgres Subtransaction Splintering and Snapshot Metadata Quarantine Guardrail - Enforces strict limits against nested subtransactions and savepoint proliferation in PostgreSQL OLTP workloads. Uncontrolled savepoint chains overflow backend ProcArray subxid caches (exceeding the 64-entry inline ceiling), triggering global SubtransSLRULock contention, snapshot bloat, and accelerated transaction ID (XID) wraparound exhaustion. High-throughput database clients must decouple transient failure handling from database-level savepoints using application-tier idempotent retries.
globs: src/**/*.ts, src/**/*.js, src/repositories/**/*.ts, src/services/**/*.ts, src/**/*.sql
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/postgres-subtransaction-splintering-snapshot-quarantine"
---

# Postgres Subtransaction Splintering and Snapshot Metadata Quarantine Guardrail

> **Severity**: CRITICAL | **Category**: backend
> **Anti-Pattern Warning**: Nested Savepoints and ORM Subtransaction Splintering Saturating PGPROC SubXID Caches and SLRU Locks

## System Constraints
You are a Principal Database Reliability Engineer enforcing strict standards against PostgreSQL subtransaction (SAVEPOINT) proliferation. In PostgreSQL (including PG 16 and 17), exceeding 64 subtransaction IDs within a transaction exhausts the inline PGPROC subxid cache, causing suboverflow conditions that force every concurrent snapshot generation across the entire cluster to scan pg_subtrans disk and SLRU buffers under SubtransSLRULock. You must disallow implicit and explicit nested SAVEPOINT calls inside OLTP hot paths, disallow PL/pgSQL EXCEPTION loops, and mandate flattened single-depth transactions with application-level idempotent retry policies.

## Strict Guidelines
- Engineers MUST NEVER nest database transaction primitives or invoke `SAVEPOINT` within iterative loops or high-throughput OLTP request flows.
- Engineers MUST NOT use PL/pgSQL `BEGIN ... EXCEPTION WHEN ... END` blocks inside procedural loops, as each exception block instantiates an internal subtransaction consuming an XID upon modification.
- Code SHOULD enforce atomic bulk operations using `INSERT ... ON CONFLICT DO UPDATE` or staging tables rather than per-row savepoint-and-catch routines.
- Services MUST execute fallible third-party calls or transient validation checks outside the transactional boundary, handling retries at the application runtime layer.
- Components NEVER configure ORM clients (e.g., Prisma, TypeORM, Hibernate) to use nested transaction hooks that synthesize dynamic `SAVEPOINT` identifiers unless explicitly quarantined to non-concurrent administrative background jobs.

## Bad vs Good Implementations
### Mitigating Subtransaction Splintering in Batch Ingest

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Creating savepoints in a loop creates an avalanche of subtransactions. Once a transaction exceeds 64 subtransactions that mutate state, PostgreSQL flags the backend as suboverflowed. Consequently, every other concurrent transaction establishing a snapshot must execute SLRU lookups to inspect active subxids, collapsing engine throughput via heavy SubtransSLRU lock contention.
```typescript
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();

interface IngestPayload {
  id: string;
  data: Record<string, unknown>;
}

// ANTI-PATTERN: Spawning savepoints inside a hot loop saturates the 64-entry subxid
// inline array in PGPROC, triggering SubtransSLRULock contention across the entire cluster.
export async function ingestBatchUnsafe(items: IngestPayload[]): Promise<void> {
  await prisma.$transaction(async (tx) => {
    for (const item of items) {
      try {
        // Raw SAVEPOINT creation or nested transactional scopes inside a loop
        await tx.$executeRawUnsafe(`SAVEPOINT item_${item.id}`);
        await tx.record.create({
          data: { id: item.id, payload: JSON.stringify(item.data) },
        });
        await tx.$executeRawUnsafe(`RELEASE SAVEPOINT item_${item.id}`);
      } catch (err) {
        await tx.$executeRawUnsafe(`ROLLBACK TO SAVEPOINT item_${item.id}`);
      }
    }
  });
}
```

#### Production Standard (Correct)
> **Standard**: The safe pattern eliminates `SAVEPOINT` usage entirely by delegating conflicts to Postgres engine primitives (`skipDuplicates` / `ON CONFLICT DO NOTHING`) within a single, flat transaction. This guarantees the backend process stays within the inline `PGPROC` 64-entry cache limit, prevents SLRU contention, and safeguards snapshot metadata consistency.
```typescript
import { PrismaClient, Prisma } from '@prisma/client';
const prisma = new PrismaClient();

interface IngestPayload {
  id: string;
  data: Record<string, unknown>;
}

// PRODUCTION INVARIANT: Use atomic set-based UPSERT or single flat transaction
// with client-side retry orchestration. Zero subtransactions created.
export async function ingestBatchSafe(items: IngestPayload[]): Promise<void> {
  if (items.length === 0) return;

  // Flat atomic upsert avoiding subtransactions entirely
  await prisma.$transaction(async (tx) => {
    await tx.record.createMany({
      data: items.map((item) => ({
        id: item.id,
        payload: JSON.stringify(item.data),
      })),
      skipDuplicates: true,
    });
  }, {
    isolationLevel: Prisma.TransactionIsolationLevel.ReadCommitted,
    maxWait: 5000,
    timeout: 10000,
  });
}
```

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 Subtransaction Splintering and Snapshot Metadata Quarantine Guardrail

Postgres Subtransaction Splintering and Snapshot Metadata Quarantine Guardrail defines an industrial-grade behavioral standard for backend engineering. Enforces strict limits against nested subtransactions and savepoint proliferation in PostgreSQL OLTP workloads. Uncontrolled savepoint chains overflow backend ProcArray subxid caches (exceeding the 64-entry inline ceiling), triggering global SubtransSLRULock contention, snapshot bloat, and accelerated transaction ID (XID) wraparound exhaustion. High-throughput database clients must decouple transient failure handling from database-level savepoints using application-tier idempotent retries. 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: Nested Savepoints and ORM Subtransaction Splintering Saturating PGPROC SubXID Caches and SLRU Locks 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 DriftNested Savepoints and ORM Subtransaction Splintering Saturating PGPROC SubXID Caches and SLRU LocksCritical
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 NEVER nest database transaction primitives or invoke `SAVEPOINT` within iterative loops or high-throughput OLTP request flows.

Engineers MUST NEVER nest database transaction primitives or invoke `SAVEPOINT` within iterative loops or high-throughput OLTP request flows.

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 use PL/pgSQL `BEGIN ... EXCEPTION WHEN ... END` blocks inside procedural loops, as each exception block instantiates an internal subtransaction consuming an XID upon modification.

Engineers MUST NOT use PL/pgSQL `BEGIN ... EXCEPTION WHEN ... END` blocks inside procedural loops, as each exception block instantiates an internal subtransaction consuming an XID upon modification.

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

Code SHOULD enforce atomic bulk operations using `INSERT ... ON CONFLICT DO UPDATE` or staging tables rather than per-row savepoint-and-catch routines.

Code SHOULD enforce atomic bulk operations using `INSERT ... ON CONFLICT DO UPDATE` or staging tables rather than per-row savepoint-and-catch routines.

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 execute fallible third-party calls or transient validation checks outside the transactional boundary, handling retries at the application runtime layer.

Services MUST execute fallible third-party calls or transient validation checks outside the transactional boundary, handling retries at the application runtime layer.

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 configure ORM clients (e.g., Prisma, TypeORM, Hibernate) to use nested transaction hooks that synthesize dynamic `SAVEPOINT` identifiers unless explicitly quarantined to non-concurrent administrative background jobs.

Components NEVER configure ORM clients (e.g., Prisma, TypeORM, Hibernate) to use nested transaction hooks that synthesize dynamic `SAVEPOINT` identifiers unless explicitly quarantined to non-concurrent administrative background jobs.

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 Subtransaction Splintering and Snapshot Metadata Quarantine Guardrail critical for AI coding assistants?

Enforces strict limits against nested subtransactions and savepoint proliferation in PostgreSQL OLTP workloads. Uncontrolled savepoint chains overflow backend ProcArray subxid caches (exceeding the 64-entry inline ceiling), triggering global SubtransSLRULock contention, snapshot bloat, and accelerated transaction ID (XID) wraparound exhaustion. High-throughput database clients must decouple transient failure handling from database-level savepoints using application-tier idempotent retries. 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 (Nested Savepoints and ORM Subtransaction Splintering Saturating PGPROC SubXID Caches and SLRU Locks) 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