/explain/autovacuum_vacuum_cost_delay

autovacuum_vacuum_cost_delay

Vacuum meters itself with a token budget: page touches cost units, and when the running balance reaches autovacuum_vacuum_cost_limit, the worker sleeps autovacuum_vacuum_cost_delay milliseconds. The default fell from 20 ms to 2 ms in Postgres 12 (a 10× speedup), but clusters initialized earlier often still carry 20 ms in their config, throttling every vacuum to a crawl on hardware that stopped caring a decade ago.

DEMO — one vacuum pass, toy table14 GB heap · 1,740,000 pages
defaults (200 · 2 ms)1 min · 154.7 MB/s
sliders15 min · 15.5 MB/s
autovacuum_vacuum_cost_limit200
cost units the worker may spend before it sleeps · default 200
autovacuum_vacuum_cost_delay20 ms
how long it sleeps · default 2 ms since Postgres 12, 20 ms before
cost = pages × (0.55·hit + 0.25·miss + 0.20·dirty) · duration = cost / limit × delay
SEE ALSO
autovacuum_vacuum_cost_limitvacuum_cost_page_dirty← back to start
0 disables throttling entirely. Manual VACUUM uses vacuum_cost_delay, which defaults to 0, that is why a hand-run vacuum feels so much faster than autovacuum.
autovacuum_vacuum_cost_delay — robovac