Postgres Prepared Statement Generic vs Custom Plan Tuning Prompt
Diagnose why a parameterized/prepared query flipped to a bad generic plan after the sixth execution — and decide between plan_cache_mode, query rewrites, or letting Postgres re-plan — so latency stops spiking under skewed parameters.
- Target user
- Backend and platform engineers debugging prepared-statement plan regressions
- Difficulty
- Advanced
- Tools
- Claude, ChatGPT, Cursor
The prompt
You are a senior PostgreSQL DBA who understands the prepared-statement plan cache: Postgres builds custom plans for the first five executions, then compares their average cost against a generic plan, and may lock in the generic plan permanently. On columns with skewed data distribution this can produce a plan that is great for a common parameter and terrible for a rare one — a latency regression that appears only after the query "warms up." I will paste: - The prepared/parameterized query (or the ORM-generated SQL with $1, $2 params): [QUERY] - Postgres version and relevant settings (plan_cache_mode if set): [VERSION / SETTINGS] - Plans for the SAME query with a common param and with a skewed param, ideally from `EXPLAIN (ANALYZE, BUFFERS)` on a manually PREPAREd statement or with GENERIC_PLAN: [PLANS] - Column statistics if known (n_distinct, most_common_vals, histogram): [STATS] - How the query is issued (server-side prepare, pgbouncer pooling mode, ORM): [CLIENT] Work through this in order: 1. **Confirm this is a generic-vs-custom-plan problem** — compare the two plans. A classic tell is a generic plan using a Seq Scan or the wrong index because the planner assumed an average selectivity, while the custom plan (which sees the literal value) picks a selective Index Scan. Note the estimate-vs-actual row gap on the skewed parameter. 2. **Name the root cause** — data skew on a bound column (a few values match millions of rows, most match a handful), stale or missing extended statistics, or a partitioned table where the generic plan cannot prune. Tie each to plan evidence. 3. **Propose fixes, ranked by impact and risk** — options include: force per-execution custom plans with `plan_cache_mode = force_custom_plan` (session or per-role, with the CPU cost of re-planning noted); improve statistics (`ALTER TABLE ... ALTER COLUMN ... SET STATISTICS`, `CREATE STATISTICS`, then `ANALYZE`); rewrite to avoid a single skewed predicate; or disable server-side prepare for that one query at the driver. Give the exact command for each. 4. **Give a verification step** — how to reproduce the flip (execute the prepared statement 6+ times and re-EXPLAIN), and what should change after the fix (stable plan across parameters, estimate close to actual, no Seq Scan on the rare value). Output format: (a) one-line verdict, (b) ranked fix table [change | scope | impact | risk], (c) exact commands/settings in order, (d) how to verify the regression is gone. Guardrails: prefer the narrowest scope — set plan_cache_mode per-session or per-role, not cluster-wide, unless you have measured the CPU cost of forcing custom plans everywhere. Test on a replica with production-like data skew; a fix that helps the rare parameter must not regress the common one.
Run this prompt with AI
Test it, get an AI-improved version, or compare models — live in the Prompt Workspace. No copy-paste.
Why this prompt works
Generic-plan regressions are among the most confusing Postgres performance bugs because nothing changed in the query or the schema — the plan flipped on its own after the sixth execution when the plan cache decided the generic plan was “cheap enough.” Engineers who do not know this mechanism chase phantom causes. This prompt names the mechanism up front and forces a side-by-side comparison of the custom and generic plans, which is the only reliable way to confirm the diagnosis.
Anchoring on data skew is what makes it accurate. The generic plan is costed against average selectivity, so it is a bad fit precisely when the bound column has a lopsided distribution — a few values matching millions of rows and most matching a handful. By asking for n_distinct and most_common_vals, the prompt ties the plan choice to the statistics that actually drove it, rather than guessing.
The ranked fixes span the real toolbox — plan_cache_mode, extended statistics, query rewrites, and disabling server-side prepare at the driver — instead of jumping straight to the biggest hammer. The guardrails enforce the two things people get wrong: forcing custom plans cluster-wide (paying re-planning CPU on every query) and testing against uniform data that never reproduces the skew.
Related prompts
-
Postgres Planner Mis-Estimation & Extended Statistics Prompt
Fix bad query plans caused by wrong row estimates — correlated columns, skewed distributions, or stale stats — using ANALYZE, statistics targets, and CREATE STATISTICS rather than blunt planner hacks.
-
Postgres Keyset (Cursor) Pagination Optimization Prompt
Convert a slow OFFSET/LIMIT pagination query into stable keyset (seek) pagination that stays fast on deep pages — with a matching index and a correct tuple-comparison predicate, not a broken one-column WHERE.
-
Postgres Parallel Query Worker Tuning Prompt
Work out why a big analytical query isn't going parallel — or is spawning too many workers and starving everything else — and set the parallel GUCs from evidence in the plan instead of copy-pasted blog values.
-
Postgres Index Advisor from pg_stat_statements Prompt
Mine pg_stat_statements for your most expensive queries and get a prioritized list of missing indexes to add and redundant indexes to drop — with the write cost of each spelled out.
More Postgres prompts & error guides
Browse every Postgres prompt and troubleshooting guide in one place.
Reading prompts? Get all 500 in one free PDF
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.