Diagnostic Queries
Symptoms
A statement was cancelled because it waited longer than lock_timeout to acquire a lock. PostgreSQL raises SQLSTATE 55P03 (lock_not_available).
- The statement exceeded
lock_timeoutwhile blocked. - Another transaction held the needed lock too long.
- Common safeguard for DDL/maintenance.
What the server log shows
ERROR: canceling statement due to lock timeout
CONTEXT: while updating tuple (0,12) in relation "orders"
Why PostgreSQL raises this — what the manual says
Section 19.11.1 Statement Behavior (lock_timeout):
“Abort any statement that waits longer than the specified amount of time while attempting to acquire a lock on a table, index, row, or other database object.”
lock_timeout caps how long a statement will wait to acquire a lock. When a blocking lock isn’t released within that window, PostgreSQL cancels the waiting statement and reports 55P03.
Common causes
- A long-held lock by another transaction.
- Lock contention during DDL/maintenance.
lock_timeoutset deliberately low to fail fast.
Relevant GUC parameters
| Parameter | Default | Effect |
|---|---|---|
lock_timeout |
0 | Max time to wait for a lock before cancelling; 0 disables. |
How to fix it
- Identify and resolve the blocking transaction.
- Retry the operation when contention is lower.
- Tune
lock_timeoutto a value matching your tolerance.
Diagnostic query
SELECT pid, mode, granted, relation::regclass FROM pg_locks WHERE NOT granted;
Cross-reference ungranted locks with pg_stat_activity to find the blocker.
Related & next steps
Reference: PostgreSQL 18 Section 20.10 “Client Connection Defaults”.
Thanks — noted. This helps keep the database accurate.