Concurrency bugs are almost never about wrong SQL — they are about wrong locking assumptions. The complete PostgreSQL locking matrix.
Module 13 — Locking Internals: Row Locks, Table Locks, and Advisory Locks
What this module covers: Concurrency bugs in production are almost never about wrong SQL — they are about wrong locking assumptions. This module covers the complete PostgreSQL locking matrix from first principles: what every lock mode protects, how row-level locks differ from table-level locks, the precise semantics of
FOR UPDATEvsFOR SHAREvsFOR NO KEY UPDATE, howALTER TABLEcan silently queue behind a single open transaction and take down your application, and how advisory locks let you build distributed coordination primitives directly inside Postgres.
Why Locking Is Hard to Reason About
Postgres has multiple, overlapping lock systems that operate at different granularities simultaneously:
- Table-level locks — protect the table structure and relation-level operations
- Row-level locks — protect individual tuple modifications
- Page-level locks — internal, mostly transparent (buffer pins)
- Advisory locks — application-defined locks with no automatic semantics
Every DML statement acquires locks at multiple levels simultaneously. An UPDATE acquires a RowExclusiveLock on the table and a row-level exclusive lock on each modified tuple. The two systems interact: some table-level operations must wait for all row-level locks to be released before they can proceed.
Understanding which operations conflict — and which do not — is the difference between a schema migration that completes in 30 seconds and one that causes a 20-minute outage.
Table-Level Lock Modes
Postgres defines 8 table-level lock modes, ordered from weakest to strongest. Each mode conflicts with some modes and is compatible with others.
The Full Lock Matrix
| Lock Mode | Acquired By | Conflicts With |
|---|---|---|
ACCESS SHARE | SELECT | ACCESS EXCLUSIVE only |
ROW SHARE | SELECT FOR UPDATE/SHARE | EXCLUSIVE, ACCESS EXCLUSIVE |
ROW EXCLUSIVE | INSERT, UPDATE, DELETE | SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, ACCESS EXCLUSIVE |
SHARE UPDATE EXCLUSIVE | VACUUM, ANALYZE, CREATE INDEX CONCURRENTLY, ALTER TABLE ... VALIDATE | SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, ACCESS EXCLUSIVE |
SHARE | CREATE INDEX (non-concurrent) | ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE ROW EXCLUSIVE, EXCLUSIVE, ACCESS EXCLUSIVE |
SHARE ROW EXCLUSIVE | CREATE TRIGGER, some ALTER TABLE | ROW EXCLUSIVE and above |
EXCLUSIVE | Rare — some replication operations | Everything except ACCESS SHARE |
ACCESS EXCLUSIVE | ALTER TABLE, DROP TABLE, TRUNCATE, VACUUM FULL, LOCK TABLE | Everything including SELECT |
The critical insight: ACCESS EXCLUSIVE conflicts with every other lock mode, including plain SELECT. This is why ALTER TABLE on a busy table causes an outage.
The ALTER TABLE Outage Pattern
This is one of the most common causes of production incidents. Here is the exact mechanism:
The ALTER TABLE does not hold a lock — it is waiting for one. But its waiting position in the lock queue blocks all subsequent requests, even ones that would normally be compatible with each other.
The Correct ALTER TABLE Pattern
The window between killing queries and running the ALTER must be short — new long-running queries can start in the gap.
Lock Modes in Practice
Row-Level Locks
Table-level locks protect the schema. Row-level locks protect individual tuples from concurrent modification. They are separate systems.
The Four Row Lock Modes
FOR UPDATE
- Strongest row lock. Marks the row as being updated.
- Blocks: other
FOR UPDATE,FOR NO KEY UPDATE,FOR SHARE,FOR KEY SHARE - Use when: you intend to update or delete the row, or you need to prevent any concurrent modification
FOR NO KEY UPDATE
- Like
FOR UPDATEbut does not blockFOR KEY SHARE - Use when: updating non-key columns (foreign keys to this row remain unblocked)
- Postgres uses this internally for
UPDATEstatements that don't modify key columns
Sign in to keep reading
The rest of this module is free — sign in with Google to unlock it and track your progress.
Sign in & RegisterDiscussion
0Join the discussion