Postgres auto_explain Plan Regression Detection Prompt
Set up auto_explain to catch the query whose plan flipped in production — capturing the bad plan with timing and buffers only when it matters — then diagnose why the planner chose it, without logging every fast query.
- Target user
- DBAs and backend engineers chasing intermittent slow queries and plan flips
- Difficulty
- Advanced
- Tools
- Claude, ChatGPT, Cursor
The prompt
You are a senior PostgreSQL performance engineer who catches plan regressions in production. You know that the query which is fast in staging and slow in prod usually has a different plan, and that auto_explain is how you capture the bad plan in the act — configured to log only slow executions so it doesn't cost you or flood the logs. I will describe: - The symptom (a query that's usually fast but sometimes slow, or got slow after a deploy/data growth/ANALYZE): [SYMPTOM] - Postgres version and whether auto_explain is loadable: [VERSION] - Log destination and current logging volume tolerance: [LOG PIPELINE] - Any pg_stat_statements data you can share (mean vs max time, calls): [STATS] Work through this in order: 1. **Configure auto_explain to be safe in prod.** Give the settings with reasoning: `auto_explain.log_min_duration` set to a threshold that captures the slow tail but not routine queries; `log_analyze = on` and `log_buffers = on` for real timings (with the explicit warning that log_analyze adds per-node timing overhead — recommend `log_timing = off` or a sampling rate if that overhead is a concern); `log_nested_statements`, `log_sample_rate`, and loading via session, `ALTER SYSTEM`, or shared_preload_libraries. Explain the overhead trade-off of each. 2. **Interpret a captured regression.** Given a logged plan, walk through comparing it to the expected/good plan: estimate-vs-actual row gaps (stale stats), a Nested Loop chosen on a bad estimate where a Hash Join was right, a flipped index choice, or a generic vs custom prepared-statement plan. 3. **Correlate with the trigger**: recent ANALYZE/autovacuum, data-volume growth crossing a cost threshold, a parameter-value skew (a rare value vs a common one in a prepared statement), or a settings change. Tie the flip to a cause, not a guess. 4. **Recommend a durable fix**, ranked: refresh/extend statistics, add or reshape an index, adjust `random_page_cost`/`work_mem`, use extended statistics for correlated columns, or `plan_cache_mode` for prepared-statement plan skew. Prefer the fix that addresses the root estimate error over pinning a plan. 5. **Verify**: how to confirm the good plan is now stable (re-check auto_explain output over time, pg_stat_statements max time dropping) and how to keep a lightweight auto_explain safety net running. Output: (a) the auto_explain config with per-setting overhead notes; (b) how to read the captured plan; (c) the likely trigger; (d) a ranked fix table; (e) the verification. Guardrails: `auto_explain.log_analyze = on` instruments every matching query with timing and can add measurable overhead — set a conservative log_min_duration and/or log_sample_rate and test the overhead before enabling fleet-wide. Ship plans to a log pipeline that won't fill the disk. Prefer fixing the estimate over pinning a plan.
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
The worst query performance bugs are the intermittent ones: a statement that runs in milliseconds most of the time and seconds occasionally, because the planner flipped to a different plan. You can’t diagnose what you can’t see, and re-running the query by hand usually produces the good plan. auto_explain is the standard way to capture the bad plan in the act — but only if it’s configured to log the slow tail rather than every query, since log_analyze isn’t free. This prompt makes that overhead trade-off explicit up front.
Once a bad plan is captured, the prompt drives a real diagnosis — estimate-vs-actual gaps, join-method flips, prepared-statement plan skew — and correlates the flip with its trigger (a recent ANALYZE, data growth crossing a cost threshold, a skewed parameter). Crucially, it ranks durable fixes that correct the underlying estimate above pinning a plan, because a pinned plan just hides the next regression. The verification and lightweight safety-net guidance keep the fix honest over time.
Related prompts
-
Postgres postgres_fdw Federation Design Prompt
Design a postgres_fdw setup that actually pushes down joins, filters, and aggregates to the remote server — instead of dragging whole tables across the network — and get the security and failure modes right.
-
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 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.
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.