Postgres HOT Update and Fillfactor Tuning Prompt
Diagnose why an update-heavy table bloats and burns write I/O despite autovacuum, then decide on fillfactor, index removal, and column changes to unlock Heap-Only Tuple (HOT) updates — cutting index write amplification and bloat at the source.
- Target user
- DBAs and backend engineers tuning write-heavy Postgres tables
- Difficulty
- Advanced
- Tools
- Claude, ChatGPT, Cursor
The prompt
You are a senior PostgreSQL DBA who tunes the write path. You know that a HOT (Heap-Only Tuple) update — one that touches no indexed column and finds free space on the same page — avoids adding a new entry to every index and lets the page be cleaned by autovacuum's pruning cheaply. A non-HOT update, by contrast, writes to every index and accelerates both table and index bloat. Your job is to move an update-heavy table toward HOT updates. I will paste: - Table DDL including all indexes and current fillfactor: [DDL] - The dominant UPDATE statements (which columns they SET): [UPDATE PATTERNS] - HOT ratio evidence from pg_stat_user_tables (n_tup_upd vs n_tup_hot_upd): [STATS] - Table/index sizes and bloat estimate if known: [SIZES] - Read patterns that justify each index (so we do not drop a needed one): [READ PATTERNS] Work through this in order: 1. **Measure the current HOT ratio** — from `n_tup_hot_upd / n_tup_upd`. A low ratio on a hot-updated table is the smoking gun. Explain what is blocking HOT: either an indexed column is being updated, or pages have no free space for the new tuple version. 2. **Find the HOT blockers** — cross-reference the SET columns in the dominant UPDATEs against the indexed columns. Any overlap forces a non-HOT update. Also flag indexes on frequently churning columns (e.g. a `last_seen` or `status` timestamp) that may not earn their write cost. 3. **Propose fixes, ranked by impact and risk** — lower `fillfactor` (e.g. 90 → 70) so each page reserves room for in-place new versions (`ALTER TABLE ... SET (fillfactor = ...)`, note it only affects future writes until a REWRITE/VACUUM FULL); drop or narrow an index on a churning column so updates to it can be HOT; or split the volatile column into a separate table. Give exact DDL and the trade-off for each (more fillfactor = larger table, fewer tuples per page for reads). 4. **Give a verification step** — reset stats or note the baseline, run representative UPDATE load, and re-check that `n_tup_hot_upd / n_tup_upd` rose and that index and table growth slowed. Note that fillfactor changes need new page allocations (or a rewrite) to take effect. Output format: (a) one-line verdict with the current HOT ratio, (b) ranked fix table [change | expected HOT gain | read/space cost | risk], (c) exact DDL in order, (d) verification queries. Guardrails: never drop an index without confirming from pg_stat_user_indexes and the read patterns that nothing needs it. Test fillfactor changes on a replica — lower fillfactor trades read density and disk footprint for update efficiency, so measure both. A VACUUM FULL to apply fillfactor to existing data takes an ACCESS EXCLUSIVE lock; prefer pg_repack or a natural rewrite window.
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
Update-heavy tables that keep bloating despite a healthy autovacuum confuse a lot of engineers, because the usual advice — tune autovacuum harder — treats the symptom. The real lever is often the HOT-update ratio: whether each update can stay on its own heap page without writing to every index. This prompt puts n_tup_hot_upd / n_tup_upd front and center, which turns a vague “the table is bloating” into a measurable ratio you can move.
The diagnosis is precise because it cross-references the columns your UPDATEs actually SET against the indexed columns. That intersection is the entire game: a single index on a frequently churning column can force every update to be non-HOT, multiplying write I/O and index bloat. Surfacing that lets you make a targeted decision — drop or narrow one index, or lower fillfactor to reserve in-page room — rather than guessing.
The guardrails keep the fixes safe. Lowering fillfactor only affects future pages, so the prompt flags that applying it to existing data needs a rewrite with real lock implications; and it refuses to drop an index without usage evidence and a saved recreate statement. The verification step proves the change worked by showing the HOT ratio climb and index growth slow.
Related prompts
-
Postgres Index Bloat and REINDEX CONCURRENTLY Strategy Prompt
Turn raw index-bloat and usage stats into a ranked, safe REINDEX/DROP plan — so you reclaim space and restore performance without taking an outage or dropping an index something silently depends on.
-
Postgres VACUUM, Bloat & Autovacuum Tuning Prompt
Diagnose table and index bloat, decide between VACUUM, autovacuum tuning, and a rebuild, and produce per-table autovacuum settings — so dead tuples and wraparound risk stop quietly degrading your database.
-
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.
-
Postgres BRIN Index Design for Time-Series Tables Prompt
Decide whether a BRIN index will actually speed up your large, naturally-ordered table — and size pages_per_range correctly — instead of blindly reaching for a B-tree that bloats storage on append-only data.
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.