This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
backendcritical PriorityID: pg17-json-table-workmem-plan-invalidation-guardrail

PostgreSQL 17 JSON_TABLE Memory Allocation & Plan Invalidation Guardrail

Enforces strict row estimation, bounded buffer usage, and transactional statement-level memory controls when shredding deeply nested JSONB structures using PostgreSQL 17's SQL/JSON standard JSON_TABLE. Unconstrained nested path evaluations bypass standard statistics heuristics, resulting in catastrophic nested loop regressions and unbounded work_mem consumption under concurrent load.

Prohibited Anti-Pattern: Unbounded JSON_TABLE shredding with implicit Cartesian expansions and default planner statistics causing runaway work_mem consumption and Out-Of-Memory (OOM) backend crashes.

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: PostgreSQL 17 JSON_TABLE Memory Allocation & Plan Invalidation Guardrail - Enforces strict row estimation, bounded buffer usage, and transactional statement-level memory controls when shredding deeply nested JSONB structures using PostgreSQL 17's SQL/JSON standard JSON_TABLE. Unconstrained nested path evaluations bypass standard statistics heuristics, resulting in catastrophic nested loop regressions and unbounded work_mem consumption under concurrent load.
globs: src/**/*.ts, src/repositories/**/*.ts, src/db/**/*.ts, src/migrations/**/*.sql
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/pg17-json-table-workmem-plan-invalidation-guardrail"
---

# PostgreSQL 17 JSON_TABLE Memory Allocation & Plan Invalidation Guardrail

> **Severity**: CRITICAL | **Category**: backend
> **Anti-Pattern Warning**: Unbounded JSON_TABLE shredding with implicit Cartesian expansions and default planner statistics causing runaway work_mem consumption and Out-Of-Memory (OOM) backend crashes.

## System Constraints
You are a Principal Database Architect and Backend Systems Engineer enforcing PostgreSQL 17 JSON_TABLE invariants. You must prevent memory exhaustions and catastrophic plan regressions caused by arbitrary JSONB shredding. Mandate exact column typing, bounded work_mem overrides at transaction or statement scope, explicit error handlers, and planner cardinality guards.

## Strict Guidelines
- Engineers MUST ALWAYS isolate JSON_TABLE transforms within a dedicated transaction or local statement configuration overriding `work_mem` to prevent memory amplification across parallel worker nodes.
- Engineers MUST NEVER use `NESTED PATH` expressions inside JSON_TABLE without specifying explicit column data types, string length bounds (e.g., `VARCHAR(n)` over `TEXT`), and explicit `DEFAULT ... ON ERROR` clauses.
- Engineers MUST ALWAYS pre-filter rows using indexed JSONB operators (`@>`, `?`) in a CTE or subquery before passing documents into `JSON_TABLE`, avoiding full table table-scans driving inline JSON shredding.
- Engineers MUST NOT execute JSON_TABLE joins directly against massive transactional relations without evaluating query plans via `EXPLAIN (ANALYZE, BUFFERS)` to confirm PostgreSQL is not selecting a Nested Loop over an incorrect 100-row default estimate.
- Queries shredding heterogeneous nested structures SHOULD utilize explicit CTE materialization fences (`WITH shredded AS MATERIALIZED (...)`) when joining downstream relational entities to guarantee stable cardinality estimation.

## Bad vs Good Implementations
### Unbounded JSON_TABLE execution vs. Bounded, safe memory allocation with structural error handling

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Shredding nested arrays using unbounded types (TEXT, unbounded JSONB) inside JSON_TABLE without local work_mem tuning or ON ERROR handling exposes the database engine to OOM kills. The planner assumes default cardinalities, frequently selecting unbuffered Nested Loops over multi-megabyte JSONB documents.
```typescript
import { sql } from 'kysely';
import type { Kysely } from 'kysely';

export async function extractAuditEvents(db: Kysely<any>, batchId: string) {
  // ANTI-PATTERN: Unbounded JSON_TABLE query shredding arbitrary nested documents
  // directly inside a full scan. Defaults work_mem across all parallel backend workers,
  // omits error boundaries, and causes Cartesian plan blowup when nested structures are malformed.
  return await sql`
    SELECT 
      logs.id,
      jt.event_id,
      jt.event_type,
      jt.payload
    FROM audit_logs logs,
    JSON_TABLE(
      logs.raw_json,
      '$.events[*]'
      COLUMNS (
        event_id INT PATH '$.id',
        event_type TEXT PATH '$.type',
        NESTED PATH '$.sub_events[*]'
        COLUMNS (
          payload JSONB PATH '$'
        )
      )
    ) AS jt
    WHERE logs.batch_id = ${batchId}
  `.execute(db);
}
```

#### Production Standard (Correct)
> **Standard**: Uses a localized transaction setting a conservative work_mem limit and statement timeout. Employs a materialized CTE to ensure index-driven JSONB pre-filtering, sets strictly bounded column types (`VARCHAR(64)`), and specifies deterministic `DEFAULT ... ON EMPTY/ERROR` behaviors to safeguard the planner from memory exhaustion and abort cascades.
```typescript
import { sql } from 'kysely';
import type { Kysely } from 'kysely';

export async function extractAuditEvents(db: Kysely<any>, batchId: string) {
  // PRODUCTION INVARIANT: Statement-level work_mem limit, pre-filtered CTE fence,
  // strictly typed columns, explicit length boundaries, and defined ON EMPTY / ON ERROR handlers.
  return await db.transaction().execute(async (trx) => {
    // Bound work_mem locally for the duration of this shredding transaction
    await sql`SET LOCAL work_mem = '64MB'`.execute(trx);
    await sql`SET LOCAL statement_timeout = '5000ms'`.execute(trx);

    return await sql`
      WITH filtered_logs AS MATERIALIZED (
        SELECT id, raw_json
        FROM audit_logs
        WHERE batch_id = ${batchId}
          AND raw_json ? 'events'
      )
      SELECT 
        fl.id,
        jt.event_id,
        jt.event_type,
        jt.payload
      FROM filtered_logs fl,
      JSON_TABLE(
        fl.raw_json,
        '$.events[*]'
        COLUMNS (
          event_id BIGINT PATH '$.id' ERROR ON ERROR,
          event_type VARCHAR(64) PATH '$.type' DEFAULT 'UNKNOWN' ON EMPTY DEFAULT 'INVALID' ON ERROR,
          NESTED PATH '$.sub_events[*]'
          COLUMNS (
            payload VARCHAR(255) PATH '$.action' DEFAULT NULL ON EMPTY
          )
        )
      ) AS jt
    `.execute(trx);
  });
}
```

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: PostgreSQL 17 JSON_TABLE Memory Allocation & Plan Invalidation Guardrail

PostgreSQL 17 JSON_TABLE Memory Allocation & Plan Invalidation Guardrail defines an industrial-grade behavioral standard for backend engineering. Enforces strict row estimation, bounded buffer usage, and transactional statement-level memory controls when shredding deeply nested JSONB structures using PostgreSQL 17's SQL/JSON standard JSON_TABLE. Unconstrained nested path evaluations bypass standard statistics heuristics, resulting in catastrophic nested loop regressions and unbounded work_mem consumption under concurrent load. 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: Unbounded JSON_TABLE shredding with implicit Cartesian expansions and default planner statistics causing runaway work_mem consumption and Out-Of-Memory (OOM) backend crashes. 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 DriftUnbounded JSON_TABLE shredding with implicit Cartesian expansions and default planner statistics causing runaway work_mem consumption and Out-Of-Memory (OOM) backend crashes.Critical
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 isolate JSON_TABLE transforms within a dedicated transaction or local statement configuration overriding `work_mem` to prevent memory amplification across parallel worker nodes.

Engineers MUST ALWAYS isolate JSON_TABLE transforms within a dedicated transaction or local statement configuration overriding `work_mem` to prevent memory amplification across parallel worker nodes.

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 NEVER use `NESTED PATH` expressions inside JSON_TABLE without specifying explicit column data types, string length bounds (e.g., `VARCHAR(n)` over `TEXT`), and explicit `DEFAULT ... ON ERROR` clauses.

Engineers MUST NEVER use `NESTED PATH` expressions inside JSON_TABLE without specifying explicit column data types, string length bounds (e.g., `VARCHAR(n)` over `TEXT`), and explicit `DEFAULT ... ON ERROR` clauses.

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 ALWAYS pre-filter rows using indexed JSONB operators (`@>`, `?`) in a CTE or subquery before passing documents into `JSON_TABLE`, avoiding full table table-scans driving inline JSON shredding.

Engineers MUST ALWAYS pre-filter rows using indexed JSONB operators (`@>`, `?`) in a CTE or subquery before passing documents into `JSON_TABLE`, avoiding full table table-scans driving inline JSON shredding.

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

Engineers MUST NOT execute JSON_TABLE joins directly against massive transactional relations without evaluating query plans via `EXPLAIN (ANALYZE, BUFFERS)` to confirm PostgreSQL is not selecting a Nested Loop over an incorrect 100-row default estimate.

Engineers MUST NOT execute JSON_TABLE joins directly against massive transactional relations without evaluating query plans via `EXPLAIN (ANALYZE, BUFFERS)` to confirm PostgreSQL is not selecting a Nested Loop over an incorrect 100-row default estimate.

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

Queries shredding heterogeneous nested structures SHOULD utilize explicit CTE materialization fences (`WITH shredded AS MATERIALIZED (...)`) when joining downstream relational entities to guarantee stable cardinality estimation.

Queries shredding heterogeneous nested structures SHOULD utilize explicit CTE materialization fences (`WITH shredded AS MATERIALIZED (...)`) when joining downstream relational entities to guarantee stable cardinality estimation.

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 PostgreSQL 17 JSON_TABLE Memory Allocation & Plan Invalidation Guardrail critical for AI coding assistants?

Enforces strict row estimation, bounded buffer usage, and transactional statement-level memory controls when shredding deeply nested JSONB structures using PostgreSQL 17's SQL/JSON standard JSON_TABLE. Unconstrained nested path evaluations bypass standard statistics heuristics, resulting in catastrophic nested loop regressions and unbounded work_mem consumption under concurrent load. 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 (Unbounded JSON_TABLE shredding with implicit Cartesian expansions and default planner statistics causing runaway work_mem consumption and Out-Of-Memory (OOM) backend crashes.) 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

PostgreSQL