CertGrid CertGrid
Concepts·PostgreSQL

PostgreSQL VACUUM and Table Bloat

An UPDATE of 133,333 rows leaves 133,333 dead tuples. VACUUM clears them and the table stays at exactly 47 MB. Only VACUUM FULL returns space - and it rewrites the whole table under an exclusive lock to do it.

Performance Guide 35 of 47 Advanced

This is a direct consequence of MVCC: an UPDATE writes a new row version and leaves the old one for concurrent readers. Every PostgreSQL table works this way, and autovacuum exists to manage it.

Every command on this page ran on db-a01.
Server NameIP AddressOSRolesCPURAMHDD
db-a01192.168.0.81Ubuntu 26.04 LTSPrimary / Source / Replica Set Member 12 Core4 GB50 GB

This guide includes

Use this when a table has grown and deleting or updating rows does not shrink it. This matters because VACUUM makes space reusable without returning it - only a rewrite gives the disk back.

Before you start

  1. Update a third of the rows and count the dead ones

  2. Vacuum, and watch the size not change

  3. Rewrite the table to get the space back

  4. Read the settings that make this automatic

Official sources