Table of contentsClick link to navigate to the desired location
This content has been automatically translated from Ukrainian.
PostgreSQL has a mechanism called MVCC (I will explain in more detail below) - multi-version concurrency control. When you update or delete data, old versions of rows do not disappear immediately. They remain in the table files as "dead weight." Over time, these rows accumulate, tables bloat, indexes lose efficiency, and queries start to run slower.
To keep the database in a healthy state, PostgreSQL uses a process called VACUUM. It removes unused versions of rows, frees up space, and helps update statistics for the query planner. This is a kind of cleanup that usually does not need to be run manually, as the automatic autovacuum typically takes care of it.
There is also VACUUM FULL - a more radical version. It not only cleans up the "garbage" but also physically rebuilds the table, returning space to the file system. The cost is a complete lock on the table during the operation. Therefore, FULL is used rarely and mainly during night windows or after mass deletions.
Without VACUUM, PostgreSQL gradually degrades: tables grow, indexes lose accuracy, queries become slow, and autovacuum may start to operate too aggressively. Thus, VACUUM is not just a technical tool but a fundamental mechanism that allows PostgreSQL to maintain performance for many years.
MVCC (Multi-Version Concurrency Control)
MVCC (Multi-Version Concurrency Control) is the way PostgreSQL and other DBMS allow many clients to read and modify data simultaneously without blocking that paralyzes operations.
In regular databases without MVCC, simultaneous writes and reads can create conflicts. MVCC resolves this by: when you update a row, the database does not overwrite it on top of the old one but creates a new version. The old one remains accessible to those transactions that still "see" it. Each transaction works with its own snapshot of the data, without interfering with others.
The advantage is simple - readers do not block writes, and writes do not block readers. This is why PostgreSQL can handle a large number of parallel operations without significant delays.
The downside is also obvious - old versions accumulate. And it is VACUUM that is responsible for removing these "dead" rows and keeping the database in a clean state.
This post doesn't have any additions from the author yet.