postgres index bloat detection and rebuild
Explains how to detect Postgres index bloat and rebuild indexes safely. Use it when index sizes grow without row growth, when autovacuum seems behind, or before a REINDEX. Not for table bloat or general vacuum tuning.
TL;DR
Index bloat is dead space inside indexes left by updates and deletes; detect it with pgstattuple or a bloat-estimate query against pg_class, then rebuild with REINDEX CONCURRENTLY to avoid locking writes. If bloat keeps coming back, autovacuum is too slow or fillfactor is wrong, and rebuilding alone just buys time. Always measure before and after so you know the rebuild was worth it.
The query
postgres index bloat detection and rebuildUse this when
- an index is much larger than the table data it covers
- you suspect autovacuum is not keeping up with updates
- you are planning a REINDEX and want the non-blocking variant
Not for
- table (heap) bloat, which needs VACUUM FULL or CLUSTER instead
- general autovacuum tuning without a bloat diagnosis first
Steps
- Estimate bloat with a bloat query or pgstattuple on the suspect index. Compare index size to expected size for the row count.
Expected output: You have a bloat percentage or byte estimate for the index.
- Check autovacuum stats first: if the table is rarely vacuumed, fix that before rebuilding, or the bloat returns.
Expected output: pgstatuser_tables shows recent vacuum activity on the table.
- Rebuild with REINDEX INDEX CONCURRENTLY so reads and writes keep working during the rebuild.
Expected output: The rebuild finishes without blocking production traffic.
- Consider lowering fillfactor on heavily updated indexes so future updates reuse page space instead of bloating.
Expected output: The index's fillfactor matches its update pattern.
- Record sizes before and after, and set up a periodic bloat check so it does not silently regrow.
Expected output: You have a before/after number and a recurring check in place.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_3tLJlBQHSO3dBRC-ZrkYzg
Maintainer review
No maintainer verification is recorded for this version.
This records the version a maintainer checked. It does not assert that the version is the latest upstream release.