This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
backendcritical PriorityID: pgx-v5-pipeline-batch-saturation-guardrail

pgx v5 Pipeline Concurrency & Batch Buffer Saturation Guardrail

Mandates deterministic chunking, strict result-drain loops, and explicit context timeouts when using jackc/pgx/v5 Batch and Pipeline APIs. Unbounded batch queuing triggers full-duplex TCP socket buffer deadlocks (SO_SNDBUF/SO_RCVBUF saturation) between Go runtimes and PostgreSQL, leading to silent connection-pool starvation.

Prohibited Anti-Pattern: Unbounded pgx.Batch Queueing and Deferred Result Consumption Inducing Full-Duplex Socket Deadlocks

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: pgx v5 Pipeline Concurrency & Batch Buffer Saturation Guardrail - Mandates deterministic chunking, strict result-drain loops, and explicit context timeouts when using jackc/pgx/v5 Batch and Pipeline APIs. Unbounded batch queuing triggers full-duplex TCP socket buffer deadlocks (SO_SNDBUF/SO_RCVBUF saturation) between Go runtimes and PostgreSQL, leading to silent connection-pool starvation.
globs: **/*.go
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/pgx-v5-pipeline-batch-saturation-guardrail"
---

# pgx v5 Pipeline Concurrency & Batch Buffer Saturation Guardrail

> **Severity**: CRITICAL | **Category**: backend
> **Anti-Pattern Warning**: Unbounded pgx.Batch Queueing and Deferred Result Consumption Inducing Full-Duplex Socket Deadlocks

## System Constraints
You are a Principal Backend Architect enforcing strict execution boundaries on jackc/pgx/v5 batching and pipelining. Unbounded batches or deferred result consumption across TCP sockets inevitably trigger full-duplex socket buffer deadlocks and pool starvation under high throughput. Enforce deterministic chunk sizes (<= 250), immediate batch result closure patterns, and context deadlines.

## Strict Guidelines
- Engineers MUST partition large datasets into deterministic chunks (e.g., 100 to 250 statements) before enqueuing them into a pgx.Batch.
- Engineers MUST ALWAYS defer BatchResults.Close() immediately after SendBatch to guarantee pool connection return and prevent leakages.
- Engineers MUST sequentially consume all BatchResults (via Exec, Query, or QueryRow) corresponding to every queued query; abandoning or prematurely exiting result iteration deadlocks the underlying connection.
- Engineers MUST NOT execute unbounded slices or slice sizes determined by raw client inputs directly inside a single pgx.Batch.
- Code SHOULD enforce an explicit context.WithTimeout per batch iteration to break connection deadlocks if the socket buffer saturates.
- Engineers MUST verify the error returned by BatchResults.Close(), as deferred constraint violations and socket transmission errors only surface upon final buffer flushing.

## Bad vs Good Implementations
### Unbounded Batch Queueing and Incomplete Draining (Deadlock & Starvation)

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Queuing thousands of statements in one batch without chunking saturates the kernel TCP send and receive socket buffers. If PostgreSQL fills its receive buffer while trying to send execution results back over a saturated client receive buffer, a TCP deadlock halts the process. In addition, abandoning the batch on error without closing BatchResults leaves the pool connection permanently locked.
```go
package repository

import (
	"context"
	"github.com/jackc/pgx/v5/pgxpool"
)

type Event struct {
	ID      string
	Payload []byte
}

func IngestEventsUnbounded(ctx context.Context, pool *pgxpool.Pool, events []Event) error {
	// ANTI-PATTERN: Enqueuing thousands of items into a single pgx.Batch fills
	// kernel TCP send buffers (SO_SNDBUF). Postgres responds with data filling
	// SO_RCVBUF, causing bidirectional TCP window zero-stalls and deadlocks.
	batch := &pgxpool.Batch{}
	for _, ev := range events {
		batch.Queue("INSERT INTO events (id, payload) VALUES ($1, $2)", ev.ID, ev.Payload)
	}

	br := pool.SendBatch(ctx, batch)
	// ANTI-PATTERN: Missing defer br.Close(). If an error occurs in the loop,
	// the connection remains occupied and unreturned to pgxpool.
	for range events {
		_, err := br.Exec()
		if err != nil {
			return err // Leaks underlying pool connection
		}
	}
	return nil
}
```

#### Production Standard (Correct)
> **Standard**: Splitting workloads into explicit chunks (max 250 queries) ensures that network socket buffers are never overwhelmed, precluding zero-window deadlocks. Wrapping execution in an explicit timeout context bounds connection occupancy. Deferring `br.Close()` immediately ensures proper resource reclamation on error, and asserting `br.Close()` at the end captures deferred protocol-level errors.
```go
package repository

import (
	"context"
	"fmt"
	"time"

	"github.com/jackc/pgx/v5"
	"github.com/jackc/pgx/v5/pgxpool"
)

type Event struct {
	ID      string
	Payload []byte
}

const maxBatchChunkSize = 250

func IngestEventsChunked(ctx context.Context, pool *pgxpool.Pool, events []Event) error {
	// INVARIANT: Bounded chunk sizes prevent TCP socket-buffer saturation
	for i := 0; i < len(events); i += maxBatchChunkSize {
		end := i + maxBatchChunkSize
		if end > len(events) {
			end = len(events)
		}
		chunk := events[i:end]

		if err := executeBatchChunk(ctx, pool, chunk); err != nil {
			return fmt.Errorf("executing batch chunk at offset %d: %w", i, err)
		}
	}
	return nil
}

func executeBatchChunk(ctx context.Context, pool *pgxpool.Pool, chunk []Event) error {
	chunkCtx, cancel := context.WithTimeout(ctx, 30*time.Second)
	defer cancel()

	batch := &pgx.Batch{}
	for _, ev := range chunk {
		batch.Queue("INSERT INTO events (id, payload) VALUES ($1, $2)", ev.ID, ev.Payload)
	}

	br := pool.SendBatch(chunkCtx, batch)
	// INVARIANT: Always defer br.Close() to drain unread responses and return conn to pool
	defer br.Close()

	for range chunk {
		if _, err := br.Exec(); err != nil {
			return fmt.Errorf("executing statement in batch: %w", err)
		}
	}

	// INVARIANT: Must check br.Close() to capture deferred constraint violations or transmission errors
	if err := br.Close(); err != nil {
		return fmt.Errorf("closing batch results: %w", err)
	}

	return nil
}
```

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: pgx v5 Pipeline Concurrency & Batch Buffer Saturation Guardrail

pgx v5 Pipeline Concurrency & Batch Buffer Saturation Guardrail defines an industrial-grade behavioral standard for backend engineering. Mandates deterministic chunking, strict result-drain loops, and explicit context timeouts when using jackc/pgx/v5 Batch and Pipeline APIs. Unbounded batch queuing triggers full-duplex TCP socket buffer deadlocks (SO_SNDBUF/SO_RCVBUF saturation) between Go runtimes and PostgreSQL, leading to silent connection-pool starvation. 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 pgx.Batch Queueing and Deferred Result Consumption Inducing Full-Duplex Socket Deadlocks 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 pgx.Batch Queueing and Deferred Result Consumption Inducing Full-Duplex Socket DeadlocksCritical
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 partition large datasets into deterministic chunks (e.g., 100 to 250 statements) before enqueuing them into a pgx.Batch.

Engineers MUST partition large datasets into deterministic chunks (e.g., 100 to 250 statements) before enqueuing them into a pgx.Batch.

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 defer BatchResults.Close() immediately after SendBatch to guarantee pool connection return and prevent leakages.

Engineers MUST ALWAYS defer BatchResults.Close() immediately after SendBatch to guarantee pool connection return and prevent leakages.

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 sequentially consume all BatchResults (via Exec, Query, or QueryRow) corresponding to every queued query

Engineers MUST sequentially consume all BatchResults (via Exec, Query, or QueryRow) corresponding to every queued query; abandoning or prematurely exiting result iteration deadlocks the underlying connection.

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 unbounded slices or slice sizes determined by raw client inputs directly inside a single pgx.Batch.

Engineers MUST NOT execute unbounded slices or slice sizes determined by raw client inputs directly inside a single pgx.Batch.

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

Code SHOULD enforce an explicit context.WithTimeout per batch iteration to break connection deadlocks if the socket buffer saturates.

Code SHOULD enforce an explicit context.WithTimeout per batch iteration to break connection deadlocks if the socket buffer saturates.

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

Engineers MUST verify the error returned by BatchResults.Close(), as deferred constraint violations and socket transmission errors only surface upon final buffer flushing.

Engineers MUST verify the error returned by BatchResults.Close(), as deferred constraint violations and socket transmission errors only surface upon final buffer flushing.

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 pgx v5 Pipeline Concurrency & Batch Buffer Saturation Guardrail critical for AI coding assistants?

Mandates deterministic chunking, strict result-drain loops, and explicit context timeouts when using jackc/pgx/v5 Batch and Pipeline APIs. Unbounded batch queuing triggers full-duplex TCP socket buffer deadlocks (SO_SNDBUF/SO_RCVBUF saturation) between Go runtimes and PostgreSQL, leading to silent connection-pool starvation. 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 pgx.Batch Queueing and Deferred Result Consumption Inducing Full-Duplex Socket Deadlocks) 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

pgx