← Lessons

quiz vs the machine

Silver1080

Databases

Postgres MVCC And Tuples

How Postgres lets readers and writers avoid blocking each other by keeping multiple row versions.

5 min read · intro · beat Silver to climb

Why versions exist

Postgres uses Multi Version Concurrency Control so a reader never has to wait for a writer and a writer never blocks a reader. Instead of overwriting a row in place, an update writes a brand new copy of the row, called a tuple, and leaves the old one behind for transactions that still need it.

Tuple bookkeeping

Every tuple carries two hidden system columns:

  • xmin is the transaction id that created the tuple.
  • xmax is the transaction id that deleted or replaced it, or zero if it is still live.

When your transaction reads a table, Postgres compares each tuple's xmin and xmax against your snapshot to decide which single version you are allowed to see.

What an update really does

  • An update marks the old tuple with an xmax pointing at the current transaction.
  • It inserts a fresh tuple with a new xmin.
  • Both copies sit in the table until cleanup removes the dead one.

This means updates and deletes create dead tuples that take space until reclaimed. Heavy churn can bloat a table even though the live row count is small.

Key idea

MVCC keeps old and new tuple versions side by side so concurrent transactions each see a consistent snapshot, at the cost of dead tuples that must be cleaned up later.

Check yourself

Answer to earn rating on the learn ladder.

1. What do xmin and xmax record on a tuple?

2. What does an UPDATE actually do to a row in Postgres?