PostgreSQL autovacuum not triggering on large high-churn table causing query slowdown
Problem
Queries on a heavily updated PostgreSQL table degrade over time despite indexes being present. EXPLAIN ANALYZE shows sequential scans. pg_stat_user_tables shows n_dead_tup in the millions and last_autovacuum is hours or days ago. The default autovacuum_vacuum_scale_factor of 0.2 (20%) means autovacuum waits until 20% of the table is dead tuples โ on a 50M row table that is 10M dead tuples before autovacuum triggers.
Error Output
Seq Scan on orders (cost=0.00..4523432.00 rows=8234521 width=312) (actual time=0.023..45234.432 rows=8234521 loops=1)
Unverified for your environment
Select your OS to check compatibility.
1 Fix
Tune autovacuum settings per-table and run VACUUM ANALYZE manually
The default scale_factor of 0.2 (20%) means autovacuum only triggers after 20% of rows are dead. On large tables this can be millions of rows. Lowering the threshold per-table makes autovacuum run more frequently.
Trust Score
5 verifications
- 1
Check dead tuple count
Identify the bloated table:
sqlSELECT relname, n_dead_tup, n_live_tup, last_autovacuum FROM pg_stat_user_tables ORDER BY n_dead_tup DESC LIMIT 10; - 2
Run VACUUM ANALYZE immediately
Clean up existing dead tuples now:
sqlVACUUM ANALYZE your_table_name; - 3
Set aggressive autovacuum for high-churn tables
Lower the scale factor so autovacuum triggers earlier:
sqlALTER TABLE your_table_name SET ( autovacuum_vacuum_scale_factor = 0.01, autovacuum_analyze_scale_factor = 0.005, autovacuum_vacuum_cost_delay = 2 );
Validation
EXPLAIN ANALYZE shows Index Scan instead of Seq Scan after vacuum. Query time improves significantly.
Verification Summary
Sign in to verify this fix
Environment
- Product
- PostgreSQL
- Version
- 15
- Environment
- production
Submitted by
Alex Chen
2450 rep