↑↓ select ↵ open ⌫ change scope Open full search

PG.CENTER connects PostgreSQL documentation, reference, and ecosystem knowledge. Maintained by Pigsty.

Reference / Lock Modes

PostgreSQL Lock Modes

Eight table lock modes and four row lock modes, their compatibility, and the SQL commands that acquire them. Select a version to read its pinned source definitions.

Current

Table lock compatibility 8 × 8

Rows show requested locks and columns show locks held by another transaction, on the same object. ROW in a table lock's name does not make it a row lock.

  • × Conflict
  • · Compatible
Table lock conflict matrix. Rows are requested locks; columns are held locks. × means table conflict; · means compatible.
Held →Requested ↓ ASRSRXSUESSRXXAX
ACCESS SHARE
ROW SHARE
ROW EXCLUSIVE
SHARE UPDATE EXCLUSIVE
SHARE
SHARE ROW EXCLUSIVE
EXCLUSIVE
ACCESS EXCLUSIVE

Select a cell to compare requested and held modes. Use the arrow keys to move through the matrix.

Combined table and row locks 14 × 14

Four SELECT FOR combinations appear under ROW SHARE; two writing combinations appear under ROW EXCLUSIVE. These are eight table-only entries plus six table-and-row combinations, still representing 12 lock modes.

  • × Table conflict, even on different rows
  • ● Conflict on the same row only
  • · Compatible modes
Combined table and row lock matrix. Rows are requested locks; columns are held locks. × means table conflict; · means compatible; ● means conflict on the same row only. Indented entries acquire both the parent table mode and the row mode.
Held →Requested ↓ ASROW SHAREROW EXCLUSIVESUESSRXXAX
Table onlyTable onlyFKSFSFNKUFUTable onlyFNKUFUTable onlyTable onlyTable onlyTable onlyTable only
ACCESS SHARETable only
ROW SHARETable only
FOR KEY SHARE
FOR SHARE
FOR NO KEY UPDATE
FOR UPDATE
ROW EXCLUSIVETable only
FOR NO KEY UPDATE
FOR UPDATE
SHARE UPDATE EXCLUSIVETable only
SHARETable only
SHARE ROW EXCLUSIVETable only
EXCLUSIVETable only
ACCESS EXCLUSIVETable only

Select a cell to compare requested and held modes. Use the arrow keys to move through the matrix.

Both operations are assumed to use the same table. Indented entries acquire both the parent table mode and the listed row mode. Groups describe commonly combined modes, not a linear ordering of lock strength.

Abbreviations: AS ACCESS SHARE · RS ROW SHARE · RX ROW EXCLUSIVE · SUE SHARE UPDATE EXCLUSIVE · S SHARE · SRX SHARE ROW EXCLUSIVE · X EXCLUSIVE · AX ACCESS EXCLUSIVE · FKS FOR KEY SHARE · FS FOR SHARE · FNKU FOR NO KEY UPDATE · FU FOR UPDATE

12 lock modes

Table lock

ROW EXCLUSIVE

Details →
Details →

Conflicts with the ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, and ACCESS EXCLUSIVE lock modes. This mode protects a table against concurrent data changes, and is self-exclusive so that only one session can hold it at a time.

CREATE TRIGGER · LOCK TABLE … IN SHARE ROW EXCLUSIVE MODE · ALTER TABLE … ENABLE / DISABLE TRIGGER · ALTER TABLE … ADD FOREIGN KEY [NOT VALID] (referencing table) · ALTER TABLE … ADD FOREIGN KEY [NOT VALID] (referenced table)

Details →

Conflicts with locks of all modes (ACCESS SHARE, ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, and ACCESS EXCLUSIVE). This mode guarantees that the holder is the only transaction accessing the table in any way.

REFRESH MATERIALIZED VIEW (without CONCURRENTLY) · DROP TABLE · DROP INDEX (without CONCURRENTLY) · TRUNCATE · CLUSTER · VACUUM FULL · VACUUM (tail truncation) · REINDEX (index being rebuilt) · LOCK TABLE … IN ACCESS EXCLUSIVE MODE · ALTER TABLE … ADD COLUMN · ALTER TABLE … DROP COLUMN · ALTER TABLE … ALTER COLUMN … SET / DROP DEFAULT · ALTER TABLE … ALTER COLUMN … TYPE · ALTER TABLE … ALTER COLUMN … SET STORAGE · ALTER TABLE … ALTER COLUMN … SET COMPRESSION · ALTER TABLE … SET TABLESPACE · ALTER TABLE … SET LOGGED / UNLOGGED · ALTER TABLE … SET ACCESS METHOD · ALTER TABLE … DROP CONSTRAINT · ALTER TABLE … ALTER CONSTRAINT · ALTER TABLE … ALTER COLUMN … SET NOT NULL · ALTER TABLE … ALTER COLUMN … DROP NOT NULL · ALTER TABLE … ENABLE / DISABLE RULE · ALTER TABLE … ENABLE / DISABLE ROW LEVEL SECURITY · ALTER TABLE … FORCE / NO FORCE ROW LEVEL SECURITY · ALTER TABLE … ALTER COLUMN … DROP EXPRESSION · ALTER TABLE … ALTER COLUMN … SET EXPRESSION · ALTER TABLE … ALTER COLUMN … SET GENERATED / RESTART / SET sequence_option · ALTER TABLE … ALTER COLUMN … ADD GENERATED … AS IDENTITY · ALTER TABLE … ALTER COLUMN … DROP IDENTITY · ALTER TABLE … INHERIT / NO INHERIT (child table) · ALTER TABLE … OWNER TO · ALTER TABLE … REPLICA IDENTITY · ALTER TABLE … RENAME · ALTER TABLE … ADD CONSTRAINT (CHECK / UNIQUE / PRIMARY KEY / EXCLUDE) · ALTER TABLE … ATTACH PARTITION (partition being attached) · ALTER TABLE … ATTACH PARTITION (default partition) · ALTER TABLE … DETACH PARTITION (parent table) · ALTER TABLE … DETACH PARTITION (partition being detached) · ALTER TABLE … DETACH PARTITION … CONCURRENTLY (partition, final phase) · ALTER INDEX … SET TABLESPACE · ALTER INDEX … SET / RESET (fillfactor = …) · ALTER INDEX … ATTACH PARTITION

Details →

Behaves similarly to FOR SHARE, except that the lock is weaker: SELECT FOR UPDATE is blocked, but not SELECT FOR NO KEY UPDATE. A key-shared lock blocks other transactions from performing DELETE or any UPDATE that changes the key values, but not other UPDATE, and neither does it prevent SELECT FOR NO KEY UPDATE, SELECT FOR SHARE, or SELECT FOR KEY SHARE.

SELECT FOR KEY SHARE · INSERT (foreign-key check) · UPDATE (foreign-key check) · COPY … FROM (foreign-key check) · MERGE (foreign-key check)

Details →
Row lock

FOR SHARE

Behaves similarly to FOR NO KEY UPDATE, except that it acquires a shared lock rather than exclusive lock on each retrieved row. A shared lock blocks other transactions from performing UPDATE, DELETE, SELECT FOR UPDATE or SELECT FOR NO KEY UPDATE on these rows, but it does not prevent them from performing SELECT FOR SHARE or SELECT FOR KEY SHARE.

SELECT FOR SHARE

Details →
Row lock

FOR UPDATE

FOR UPDATE causes the rows retrieved by the SELECT statement to be locked as though for update. This prevents them from being locked, modified or deleted by other transactions until the current transaction ends. That is, other transactions that attempt UPDATE, DELETE, SELECT FOR UPDATE, SELECT FOR NO KEY UPDATE, SELECT FOR SHARE or SELECT FOR KEY SHARE of these rows will be blocked until the current transaction ends; conversely, SELECT FOR UPDATE will wait for a concurrent transaction that has run any of those commands on the same row, and will then lock and return the updated row (or no row, if the row was deleted). Within a REPEATABLE READ or SERIALIZABLE transaction, however, an error will be thrown if a row to be locked has changed since the transaction started. For further discussion see Data Consistency Checks at the Application Level.

SELECT FOR UPDATE · UPDATE (key update) · DELETE · MERGE … WHEN MATCHED THEN DELETE / UPDATE (key) · INSERT … ON CONFLICT DO UPDATE (key)

Details →

Commands and lock modes

A command can acquire different modes on different objects and at different stages. Links preserve the selected PostgreSQL 18 version.

SQL commandAssociated modesObject, phase and conditions
SELECTRead referenced tables without a FOR locking clause. Source
COPY … TORead the source table. COPY (query) TO follows the locks required by that query. Source
LOCK TABLE … IN ACCESS SHARE MODERequest this table mode explicitly. Omitting IN MODE defaults to ACCESS EXCLUSIVE. Source
ALTER TABLE … NO INHERIT (parent table)Take ACCESS SHARE on the parent while removing inheritance. The altered child separately takes ACCESS EXCLUSIVE. Source
SELECT FOR KEY SHARELock the named table, in addition to the corresponding locks on selected rows. Source
SELECT FOR SHARELock the named table, in addition to the corresponding locks on selected rows. Source
SELECT FOR NO KEY UPDATELock the named table, in addition to the corresponding locks on selected rows. Source
SELECT FOR UPDATELock the named table, in addition to the corresponding locks on selected rows. Source
INSERT (foreign-key check)The foreign-key check runs SELECT FOR KEY SHARE on the referenced table, taking ROW SHARE there. The writing target separately holds ROW EXCLUSIVE. Source
UPDATE (foreign-key check)The foreign-key check runs SELECT FOR KEY SHARE on the referenced table, taking ROW SHARE there. The writing target separately holds ROW EXCLUSIVE. Source
COPY … FROM (foreign-key check)The foreign-key check runs SELECT FOR KEY SHARE on the referenced table, taking ROW SHARE there. The writing target separately holds ROW EXCLUSIVE. Source
MERGE (foreign-key check)The foreign-key check runs SELECT FOR KEY SHARE on the referenced table, taking ROW SHARE there. The writing target separately holds ROW EXCLUSIVE. Source
LOCK TABLE … IN ROW SHARE MODERequest this table mode explicitly. Omitting IN MODE defaults to ACCESS EXCLUSIVE. Source
ALTER TABLE … VALIDATE CONSTRAINT (referenced table)Foreign-key validation takes ROW SHARE on the referenced table and SHARE UPDATE EXCLUSIVE on the table being validated. Source
INSERTLock the insertion target. Inserting a new row is not equivalent to locking an existing row FOR UPDATE. Source
UPDATELock the target table; affected existing rows also receive row locks. Source
DELETELock the target table; deleted rows also receive FOR UPDATE locks. Source
COPY … FROMLock the target and insert new rows. This does not generally lock existing rows FOR UPDATE. Source
MERGELock the target table. Row locking depends on the INSERT, UPDATE or DELETE action actually taken. Source
LOCK TABLE … IN ROW EXCLUSIVE MODERequest this table mode explicitly. Omitting IN MODE defaults to ACCESS EXCLUSIVE. Source
UPDATE (non-key update)This write variant takes ROW EXCLUSIVE on its target table. Existing-row locks depend on the action actually performed. Source
UPDATE (key update)This write variant takes ROW EXCLUSIVE on its target table. Existing-row locks depend on the action actually performed. Source
MERGE … WHEN MATCHED THEN UPDATE (non-key)This write variant takes ROW EXCLUSIVE on its target table. Existing-row locks depend on the action actually performed. Source
MERGE … WHEN MATCHED THEN DELETE / UPDATE (key)This write variant takes ROW EXCLUSIVE on its target table. Existing-row locks depend on the action actually performed. Source
INSERT … ON CONFLICT DO UPDATE (non-key)This write variant takes ROW EXCLUSIVE on its target table. Existing-row locks depend on the action actually performed. Source
INSERT … ON CONFLICT DO UPDATE (key)This write variant takes ROW EXCLUSIVE on its target table. Existing-row locks depend on the action actually performed. Source
INSERT (foreign-key check)The write target takes ROW EXCLUSIVE. The foreign-key check takes ROW SHARE and FOR KEY SHARE on a different object: the referenced table and its matching rows. Source
UPDATE (foreign-key check)The write target takes ROW EXCLUSIVE. The foreign-key check takes ROW SHARE and FOR KEY SHARE on a different object: the referenced table and its matching rows. Source
COPY … FROM (foreign-key check)The write target takes ROW EXCLUSIVE. The foreign-key check takes ROW SHARE and FOR KEY SHARE on a different object: the referenced table and its matching rows. Source
MERGE (foreign-key check)The write target takes ROW EXCLUSIVE. The foreign-key check takes ROW SHARE and FOR KEY SHARE on a different object: the referenced table and its matching rows. Source
VACUUM (without FULL)Ordinary vacuum holds this mode; truncating empty tail pages can briefly require ACCESS EXCLUSIVE. Source
ANALYZELock the table being analyzed. Source
CREATE INDEX CONCURRENTLYLock the indexed table. Building proceeds across transactions and waits for old transactions where necessary. Source
CREATE STATISTICSLock the table whose extended statistics are being defined. Source
COMMENT ON (relation object)Lock the object being commented on. Identical modes on different objects do not conflict. Source
DROP INDEX CONCURRENTLYLock the parent table while removing the index across phases; unlike ordinary DROP INDEX this does not hold ACCESS EXCLUSIVE on the table. Source
REINDEX … CONCURRENTLYFrom PostgreSQL 12, session-level SHARE UPDATE EXCLUSIVE locks cover the rebuilt index and its table through the build, validation, swap and cleanup transactions. Source
LOCK TABLE … IN SHARE UPDATE EXCLUSIVE MODERequest this table mode explicitly. Omitting IN MODE defaults to ACCESS EXCLUSIVE. Source
ALTER TABLE … ALTER COLUMN … SET STATISTICSChange the column statistics target. Source
ALTER TABLE … ALTER COLUMN … SET (n_distinct = …)Change column statistics options; RESET has the same requirement. Source
ALTER TABLE … CLUSTER ONChoose the index for future clustering; this command does not rewrite the table. Source
ALTER TABLE … SET WITHOUT CLUSTERClear the clustering-index designation. Source
ALTER TABLE … VALIDATE CONSTRAINTValidate a constraint on this table. Foreign-key validation also accesses the referenced table. Source
ALTER TABLE … ATTACH PARTITION (parent table)The parent lock is extracted separately for every version. The table being attached additionally requires ACCESS EXCLUSIVE. From PostgreSQL 11 a default partition, if any, is also locked. Source
ALTER TABLE … DETACH PARTITION … FINALIZE (parent table)Complete an interrupted concurrent detach. The detached partition additionally requires ACCESS EXCLUSIVE. Source
ALTER TABLE … SET / RESET (fillfactor = …)Each storage parameter specifies its required mode. fillfactor can use SHARE UPDATE EXCLUSIVE. Source
ALTER TABLE … SET / RESET (autovacuum_* = …)Table autovacuum storage options use SHARE UPDATE EXCLUSIVE. Source
ALTER TABLE … SET / RESET (toast.autovacuum_* = …)These are TOAST autovacuum options. There is no generic SET TOAST subcommand; other options follow their own lock requirements. Source
ALTER TABLE … DETACH PARTITION … CONCURRENTLY (parent table)From PostgreSQL 14, concurrent detach uses two transactions. The parent holds SHARE UPDATE EXCLUSIVE and waits for transactions using the partition before finalizing. Source
ALTER TABLE … DETACH PARTITION … CONCURRENTLY (partition, first phase)In the first phase, parent and partition hold SHARE UPDATE EXCLUSIVE. The partition lock is upgraded after committing and waiting. Source
ALTER INDEX … RENAMELock the index being renamed. Source
ALTER TABLE … INHERIT (parent table)Take SHARE UPDATE EXCLUSIVE on the newly designated parent. The altered child separately takes ACCESS EXCLUSIVE. Source
CREATE INDEX (without CONCURRENTLY)Lock the indexed table, preventing concurrent writes. Source
REINDEX (parent table)Ordinary REINDEX takes SHARE on the table and ACCESS EXCLUSIVE on the index itself. The index lock is not an ACCESS EXCLUSIVE lock on the whole table. Source
LOCK TABLE … IN SHARE MODERequest this table mode explicitly. Omitting IN MODE defaults to ACCESS EXCLUSIVE. Source
CREATE TRIGGERLock the table that owns the trigger. Source
LOCK TABLE … IN SHARE ROW EXCLUSIVE MODERequest this table mode explicitly. Omitting IN MODE defaults to ACCESS EXCLUSIVE. Source
ALTER TABLE … ENABLE / DISABLE TRIGGEREnable or disable triggers, including the applicable USER, ALL, REPLICA and ALWAYS forms. Source
ALTER TABLE … ADD FOREIGN KEY [NOT VALID] (referencing table)Both referencing and referenced tables take SHARE ROW EXCLUSIVE. NOT VALID skips the initial data check, not this lock. Source
ALTER TABLE … ADD FOREIGN KEY [NOT VALID] (referenced table)The referenced table also takes SHARE ROW EXCLUSIVE, not merely ACCESS SHARE. Source
REFRESH MATERIALIZED VIEW CONCURRENTLYLock the materialized view. Ordinary reads continue; only one refresh can run on that view at a time. Source
LOCK TABLE … IN EXCLUSIVE MODERequest this table mode explicitly. Omitting IN MODE defaults to ACCESS EXCLUSIVE. Source
REFRESH MATERIALIZED VIEW (without CONCURRENTLY)Lock the materialized view, blocking ordinary reads as well. Source
DROP TABLELock the table being dropped. Dependencies and CASCADE can require additional locks. Source
DROP INDEX (without CONCURRENTLY)Take ACCESS EXCLUSIVE on the parent table, blocking reads and writes; the index is locked too. Source
TRUNCATELock each table being truncated. Options and dependencies determine the affected table set. Source
CLUSTERBlock concurrent reads and writes while rewriting the table. Source
VACUUM FULLBlock concurrent reads and writes while rewriting the table. Source
VACUUM (tail truncation)Ordinary VACUUM briefly attempts ACCESS EXCLUSIVE when returning empty tail pages to the operating system. Where supported, disabling truncation avoids this phase. Source
REINDEX (index being rebuilt)Lock the index itself. Planning also accesses indexes, so ordinary REINDEX can still block queries. Source
LOCK TABLE … IN ACCESS EXCLUSIVE MODERequest this table mode explicitly. Omitting IN MODE defaults to ACCESS EXCLUSIVE. Source
ALTER TABLE … ADD COLUMNA rewrite depends on version and default expression. Avoiding the rewrite does not reduce the listed lock mode. Source
ALTER TABLE … DROP COLUMNDrop a column and change the table definition. Source
ALTER TABLE … ALTER COLUMN … SET / DROP DEFAULTChange the column default. Source
ALTER TABLE … ALTER COLUMN … TYPEChange the column type. Whether a rewrite is needed does not change this lock requirement. Source
ALTER TABLE … ALTER COLUMN … SET STORAGEChange the column storage strategy. Source
ALTER TABLE … ALTER COLUMN … SET COMPRESSIONChange the column compression method. Source
ALTER TABLE … SET TABLESPACEMove the table to another tablespace. Source
ALTER TABLE … SET LOGGED / UNLOGGEDChange table persistence. Source
ALTER TABLE … SET ACCESS METHODChange the table access method. Source
ALTER TABLE … DROP CONSTRAINTDrop the constraint and any dependent index as applicable. Source
ALTER TABLE … ALTER CONSTRAINTChange constraint properties. Source
ALTER TABLE … ALTER COLUMN … SET NOT NULLSet a not-null constraint. Source
ALTER TABLE … ALTER COLUMN … DROP NOT NULLDrop a not-null constraint. Source
ALTER TABLE … ENABLE / DISABLE RULEEnable or disable rules. Source
ALTER TABLE … ENABLE / DISABLE ROW LEVEL SECURITYEnable or disable row-level security. Source
ALTER TABLE … FORCE / NO FORCE ROW LEVEL SECURITYChange whether the table owner is subject to row-level security. Source
ALTER TABLE … ALTER COLUMN … DROP EXPRESSIONDrop a generated-column expression. Source
ALTER TABLE … ALTER COLUMN … SET EXPRESSIONSet a generated-column expression. Source
ALTER TABLE … ALTER COLUMN … SET GENERATED / RESTART / SET sequence_optionChange identity-column properties or its implicit sequence options. This is not a standalone SET SEQUENCE subcommand. Source
ALTER TABLE … ALTER COLUMN … ADD GENERATED … AS IDENTITYAdd identity properties to a column. Source
ALTER TABLE … ALTER COLUMN … DROP IDENTITYDrop identity properties. Source
ALTER TABLE … INHERIT / NO INHERIT (child table)This entry describes the altered child table; the inheritance parent is locked separately. Source
ALTER TABLE … OWNER TOChange table ownership. Source
ALTER TABLE … REPLICA IDENTITYChange replica identity. Source
ALTER TABLE … RENAMERename the table, column or constraint. Source
ALTER TABLE … ADD CONSTRAINT (CHECK / UNIQUE / PRIMARY KEY / EXCLUDE)Ordinary constraint creation. Adding a foreign key instead uses SHARE ROW EXCLUSIVE. Source
ALTER TABLE … ATTACH PARTITION (partition being attached)The table being attached requires ACCESS EXCLUSIVE. An appropriate CHECK constraint can avoid a validation scan but not this lock. Source
ALTER TABLE … ATTACH PARTITION (default partition)From PostgreSQL 11, an existing default partition requires ACCESS EXCLUSIVE. An appropriate CHECK constraint can avoid a scan but not the lock on the default partition. Descendant scanning follows validation needs. Source
ALTER TABLE … DETACH PARTITION (parent table)Ordinary detach without CONCURRENTLY. Source
ALTER TABLE … DETACH PARTITION (partition being detached)Ordinary detach takes ACCESS EXCLUSIVE on the partition being detached. Source
ALTER TABLE … DETACH PARTITION … CONCURRENTLY (partition, final phase)The second phase takes ACCESS EXCLUSIVE on the detached partition. CONCURRENTLY is not allowed when a default partition exists. Source
ALTER INDEX … SET TABLESPACELock the index being moved, not the similarly named table. Source
ALTER INDEX … SET / RESET (fillfactor = …)Lock the index being modified. Source
ALTER INDEX … ATTACH PARTITIONFrom PostgreSQL 11, modify the partitioned parent index and the child index being attached. Source
SELECT FOR KEY SHARELock selected rows, with ROW SHARE on the target table. NOWAIT and SKIP LOCKED affect waiting, not mode compatibility. Source
INSERT (foreign-key check)Checking a non-null foreign key locks matching rows in the referenced table FOR KEY SHARE. The check can run immediately or be deferred. Cascading actions require their own UPDATE or DELETE locks. Source
UPDATE (foreign-key check)Checking a non-null foreign key locks matching rows in the referenced table FOR KEY SHARE. The check can run immediately or be deferred. Cascading actions require their own UPDATE or DELETE locks. Source
COPY … FROM (foreign-key check)Checking a non-null foreign key locks matching rows in the referenced table FOR KEY SHARE. The check can run immediately or be deferred. Cascading actions require their own UPDATE or DELETE locks. Source
MERGE (foreign-key check)Checking a non-null foreign key locks matching rows in the referenced table FOR KEY SHARE. The check can run immediately or be deferred. Cascading actions require their own UPDATE or DELETE locks. Source
SELECT FOR SHARELock selected rows, with ROW SHARE on the target table. NOWAIT and SKIP LOCKED affect waiting, not mode compatibility. Source
SELECT FOR NO KEY UPDATELock selected rows, with ROW SHARE on the target table. NOWAIT and SKIP LOCKED affect waiting, not mode compatibility. Source
UPDATE (non-key update)UPDATE uses this mode when it does not require FOR UPDATE. Key columns are columns of a unique index usable by a foreign key; partial and expression indexes do not qualify. Source
MERGE … WHEN MATCHED THEN UPDATE (non-key)The UPDATE branch actually runs and does not need FOR UPDATE. Other MERGE actions can require different row locks. Source
INSERT … ON CONFLICT DO UPDATE (non-key)Lock the existing conflicting row for UPDATE, even when the DO UPDATE WHERE condition excludes the update. Key-column changes determine the mode. Source
SELECT FOR UPDATELock selected rows, with ROW SHARE on the target table. NOWAIT and SKIP LOCKED affect waiting, not mode compatibility. Source
UPDATE (key update)Used when updating key columns of a unique index usable by a foreign key, excluding partial and expression indexes. Source
DELETELock rows being deleted, with ROW EXCLUSIVE on their table. Source
MERGE … WHEN MATCHED THEN DELETE / UPDATE (key)The matched action deletes a row or updates key columns. An insert-only action does not use this row lock. Source
INSERT … ON CONFLICT DO UPDATE (key)The conflict action updates key columns of an existing row. This is not a fixed row lock for every INSERT. Source

From compatibility to actual waits

  • Ordinary SELECT uses MVCC and takes ACCESS SHARE on referenced tables, without taking these row locks.
  • SELECT FOR also takes ROW SHARE; UPDATE and DELETE also take ROW EXCLUSIVE. A row operation can therefore wait on a table lock.
  • The matrix compares different transactions. Locks are normally held until transaction end; rolling back to a savepoint releases locks acquired since that savepoint.
  • Foreign keys, triggers, additional objects, lock queues and transaction snapshots can introduce waits beyond the listed modes. NOWAIT and SKIP LOCKED change waiting behavior.
  • Advisory locks, predicate locks and internal lightweight locks are separate mechanisms. See Explicit Locking and pg_locks.

Find blocking sessions

pg_blocking_pids() considers both holders of conflicting locks and conflicting requests ahead in the queue.

SELECT pid, usename, wait_event_type, wait_event,
       pg_blocking_pids(pid) AS blocking_pids, query
FROM pg_stat_activity
WHERE cardinality(pg_blocking_pids(pid)) > 0
ORDER BY pid;

Visibility of sessions and query text depends on privileges. Individual row locks normally do not appear in pg_locks; a row-lock wait often appears as waiting for the holding transaction.

Sources

PostgreSQL 18 · Sampled build REL_18_STABLE · 753057e340da. Conflicts, definitions and command associations refer to this fixed source build. SQL links retain the selected version.

Local English manual · Online manual

Pinned source files

Source collection date: 2026-09-27.