Lesson 6 of 8

Snapshots and Visibility: How PostgreSQL Decides What You See

Applies to PostgreSQL 13–17 Last reviewed May 2026 Grounded in source

The one thing to understand first

MVCC stores many versions of each row; a snapshot is the rule that selects which versions a statement or transaction may see. Conceptually it captures “which transactions had committed at the instant I started looking.” The struct is SnapshotData in src/include/utils/snapshot.h, built by GetSnapshotData() in src/backend/storage/ipc/procarray.c.

An isolation level is not a locking strategy — it is simply a decision about when you take your snapshot. Once you see that READ COMMITTED re-snapshots every statement while REPEATABLE READ freezes one snapshot for the whole transaction, the visibility “surprises” and the link between an idle transaction and runaway bloat both become obvious.

The three pieces that define a snapshot

  • xmin — the oldest transaction ID still running. Anything older is definitely committed or aborted (resolved).
  • xmax — the first not-yet-assigned XID. Anything at or above this had not started and is invisible.
  • xip[] — the list of XIDs that were in progress when the snapshot was taken.

With just these, visibility for any tuple is decidable: a tuple inserted by XID x is visible if x < xmax, x is not in xip[], and x committed. The deleting XID (t_xmax) is checked the same way to decide whether the version has been superseded.

This is a Pro lesson

Get every Learning Pathway and cookbook recipe — grounded in PostgreSQL source code, with diagnostics, fixes, and prevention for each topic.

Continue this lesson to learn:

  • Building a snapshot is the hot path
  • Isolation levels = when you take the snapshot
  • READ COMMITTED’s update twist
  • Snapshots pin the vacuum horizon
  • Exported and historic snapshots
  • Layer 3 — Watch it happen on your own database
  • All 36 Learning Pathway lessons
  • 170+ cookbook recipes
  • Source-grounded diagnostics & fixes

Secure checkout Cancel anytime Source-grounded

Was this helpful?

← Back to 01 — Foundations: PostgreSQL Internals 101