This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
backendcritical PriorityID: postgres-17-json-table-parallel-memory-guardrail

PostgreSQL 17 JSON_TABLE Parallel Worker Memory & Projection Guardrail

Enforces strict memory governance and cursor streaming on PostgreSQL 17 JSON_TABLE evaluations during parallel query execution. Prevents runaway per-worker work_mem consumption and Out-Of-Memory (OOM) backend crashes caused by unindexed lateral unwrapping of deeply nested JSONB payloads across parallel gather nodes.

Prohibited Anti-Pattern: Unbounded Parallel JSON_TABLE Projections on Unindexed JSONB Payloads Exhausting Per-Worker work_mem

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: PostgreSQL 17 JSON_TABLE Parallel Worker Memory & Projection Guardrail - Enforces strict memory governance and cursor streaming on PostgreSQL 17 JSON_TABLE evaluations during parallel query execution. Prevents runaway per-worker work_mem consumption and Out-Of-Memory (OOM) backend crashes caused by unindexed lateral unwrapping of deeply nested JSONB payloads across parallel gather nodes.
globs: src/**/*.ts, src/**/*.pg.ts, src/repositories/**/*.ts, src/database/**/*.ts, migrations/**/*.sql
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/postgres-17-json-table-parallel-memory-guardrail"
---

# PostgreSQL 17 JSON_TABLE Parallel Worker Memory & Projection Guardrail

> **Severity**: CRITICAL | **Category**: backend
> **Anti-Pattern Warning**: Unbounded Parallel JSON_TABLE Projections on Unindexed JSONB Payloads Exhausting Per-Worker work_mem

## System Constraints
You are a Principal Database Architect and Infrastructure Reliability Engineer enforcing strict operational constraints for PostgreSQL 17's SQL/JSON standard features. You must mandate strict per-worker work_mem isolation, bounded streaming projection via cursors, and prerequisite index scans for all JSON_TABLE queries that operate on multi-megabyte JSONB columns under high concurrency.

## Strict Guidelines
- Engineers MUST ALWAYS isolate high-cardinality JSON_TABLE projections into streaming transaction cursors (pg-query-stream) rather than eagerly loading result sets into application heap memory.
- Engineers MUST ALWAYS execute 'SET LOCAL work_mem' within a local transaction wrapper before executing parallel JSON_TABLE queries, capping per-worker memory to prevent OOM kills across Gather nodes (max_parallel_workers_per_gather * work_mem).
- Engineers MUST NOT invoke JSON_TABLE without an indexed relational predicate (e.g., GIN jsonb_path_ops or B-Tree primary keys) that prunes the candidate set before JSON structural unwrapping begins.
- Code MUST explicitly define column data types with strict lengths in the JSON_TABLE COLUMNS clause (e.g., VARCHAR(255) instead of TEXT, specific INT/NUMERIC scales) to avoid unbounded intermediate tuple allocations.
- Services MUST NEVER execute JSON_TABLE with unbounded NESTED PATH expressions inside an outer JOIN without EXPLAIN (BUFFERS, COSTS) verification confirming that parallel hash/sort operations fit strictly in worker memory without spilling to disk temp files.

## Bad vs Good Implementations
### Unbounded Eager JSON_TABLE Parallel Scan vs. Bounded Streaming Cursor with Local work_mem

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Performs an unindexed sequence scan using non-path-indexed filtering while running deeply nested JSON_TABLE projections. Under PostgreSQL 17, parallel workers expand duplicate intermediate tuples in per-worker work_mem, easily leading to query-cancellation spikes or Linux OOM killer terminating the postgres backend.
```typescript
import { Pool } from 'pg';

export async function extractTenantAuditLogs(pool: Pool, tenantId: string) {
  // Anti-Pattern: Unbounded parallel JSON_TABLE projection across unpruned JSONB documents.
  // In PG 17, parallel workers each materialize intermediate JSON path tuples in work_mem.
  // Multiplied across max_parallel_workers_per_gather, this causes immediate backend OOM.
  const query = `
    SELECT jt.*
    FROM raw_event_payloads rep,
    JSON_TABLE(
      rep.payload,
      '$.events[*]'
      COLUMNS (
        event_id TEXT PATH '$.id',
        event_type TEXT PATH '$.type',
        payload TEXT PATH '$.data',
        NESTED PATH '$.sub_events[*]'
        COLUMNS (
          sub_id TEXT PATH '$.sub_id',
          context TEXT PATH '$.details'
        )
      )
    ) AS jt
    WHERE rep.payload->>'tenant_id' = $1; -- Unindexed json extraction forces parallel Seq Scan
  `;
  const result = await pool.query(query, [tenantId]);
  return result.rows;
}
```

#### Production Standard (Correct)
> **Standard**: Enforces transaction isolation with localized work_mem and max_parallel_workers_per_gather settings. Restricts JSON_TABLE projected fields to strictly typed descriptors, filters on a native indexed column, and streams results chunk-by-chunk using pg-query-stream to guarantee stable memory profiles.
```typescript
import { Pool, PoolClient } from 'pg';
import QueryStream from 'pg-query-stream';
import { pipeline } from 'node:stream/promises';
import { Transform } from 'node:stream';

export async function extractTenantAuditLogsStream(
  pool: Pool,
  tenantId: string,
  writableDestination: NodeJS.WritableStream
): Promise<void> {
  const client: PoolClient = await pool.connect();
  try {
    await client.query('BEGIN READ ONLY');
    // Bound per-worker memory strictly for this transaction to avoid OOM under parallel gather
    await client.query("SET LOCAL work_mem = '32MB'");
    // Prevent parallel workers from exploding memory if json unwrapping is large
    await client.query('SET LOCAL max_parallel_workers_per_gather = 2');

    // Query relies on B-Tree indexed tenant_id column + restrictive data types
    const streamQuery = new QueryStream(
      `
      SELECT jt.event_id, jt.event_type, jt.sub_id
      FROM raw_event_payloads rep,
      JSON_TABLE(
        rep.payload,
        '$.events[*]'
        COLUMNS (
          event_id VARCHAR(64) PATH '$.id',
          event_type VARCHAR(100) PATH '$.type',
          NESTED PATH '$.sub_events[*]'
          COLUMNS (
            sub_id VARCHAR(64) PATH '$.sub_id'
          )
        )
      ) AS jt
      WHERE rep.tenant_id = $1 -- Relational column backed by B-Tree index
      `,
      [tenantId],
      { batchSize: 500 }
    );

    const stream = client.query(streamQuery);
    await pipeline(
      stream,
      new Transform({
        objectMode: true,
        transform(chunk, _, callback) {
          callback(null, JSON.stringify(chunk) + '\n');
        }
      }),
      writableDestination
    );

    await client.query('COMMIT');
  } catch (err) {
    await client.query('ROLLBACK');
    throw err;
  } finally {
    client.release();
  }
}
```

Recommended MCP Servers (mcp-serverlist.com)

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

Architectural Specification & Invariant Rationale

Architectural Invariant Design: PostgreSQL 17 JSON_TABLE Parallel Worker Memory & Projection Guardrail

PostgreSQL 17 JSON_TABLE Parallel Worker Memory & Projection Guardrail defines an industrial-grade behavioral standard for backend engineering. Enforces strict memory governance and cursor streaming on PostgreSQL 17 JSON_TABLE evaluations during parallel query execution. Prevents runaway per-worker work_mem consumption and Out-Of-Memory (OOM) backend crashes caused by unindexed lateral unwrapping of deeply nested JSONB payloads across parallel gather nodes. 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 Parallel JSON_TABLE Projections on Unindexed JSONB Payloads Exhausting Per-Worker work_mem 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 Parallel JSON_TABLE Projections on Unindexed JSONB Payloads Exhausting Per-Worker work_memCritical
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 high-cardinality JSON_TABLE projections into streaming transaction cursors (pg-query-stream) rather than eagerly loading result sets into application heap memory.

Engineers MUST ALWAYS isolate high-cardinality JSON_TABLE projections into streaming transaction cursors (pg-query-stream) rather than eagerly loading result sets into application heap memory.

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 execute 'SET LOCAL work_mem' within a local transaction wrapper before executing parallel JSON_TABLE queries, capping per-worker memory to prevent OOM kills across Gather nodes (max_parallel_workers_per_gather * work_mem).

Engineers MUST ALWAYS execute 'SET LOCAL work_mem' within a local transaction wrapper before executing parallel JSON_TABLE queries, capping per-worker memory to prevent OOM kills across Gather nodes (max_parallel_workers_per_gather * work_mem).

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 invoke JSON_TABLE without an indexed relational predicate (e.g., GIN jsonb_path_ops or B-Tree primary keys) that prunes the candidate set before JSON structural unwrapping begins.

Engineers MUST NOT invoke JSON_TABLE without an indexed relational predicate (e.g., GIN jsonb_path_ops or B-Tree primary keys) that prunes the candidate set before JSON structural unwrapping begins.

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 MUST explicitly define column data types with strict lengths in the JSON_TABLE COLUMNS clause (e.g., VARCHAR(255) instead of TEXT, specific INT/NUMERIC scales) to avoid unbounded intermediate tuple allocations.

Code MUST explicitly define column data types with strict lengths in the JSON_TABLE COLUMNS clause (e.g., VARCHAR(255) instead of TEXT, specific INT/NUMERIC scales) to avoid unbounded intermediate tuple allocations.

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

Services MUST NEVER execute JSON_TABLE with unbounded NESTED PATH expressions inside an outer JOIN without EXPLAIN (BUFFERS, COSTS) verification confirming that parallel hash/sort operations fit strictly in worker memory without spilling to disk temp files.

Services MUST NEVER execute JSON_TABLE with unbounded NESTED PATH expressions inside an outer JOIN without EXPLAIN (BUFFERS, COSTS) verification confirming that parallel hash/sort operations fit strictly in worker memory without spilling to disk temp files.

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 Parallel Worker Memory & Projection Guardrail critical for AI coding assistants?

Enforces strict memory governance and cursor streaming on PostgreSQL 17 JSON_TABLE evaluations during parallel query execution. Prevents runaway per-worker work_mem consumption and Out-Of-Memory (OOM) backend crashes caused by unindexed lateral unwrapping of deeply nested JSONB payloads across parallel gather nodes. 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 Parallel JSON_TABLE Projections on Unindexed JSONB Payloads Exhausting Per-Worker work_mem) 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