Diagnostic Queries
Symptoms
A long-running query tried to read data that has since been removed because the snapshot exceeded old_snapshot_threshold. PostgreSQL raises SQLSTATE 72000 (snapshot_too_old).
- A very old snapshot accessed pages whose old rows were vacuumed.
- Only occurs when
old_snapshot_thresholdis enabled. - Protects against bloat from extremely long transactions.
What the server log shows
ERROR: snapshot too old
Why PostgreSQL raises this — what the manual says
As Section 19.4 Resource Consumption (historical old_snapshot_threshold) explains:
This error originated from the old_snapshot_threshold mechanism, which bounded how long a snapshot could be used before the pages it relied on could be reclaimed; a long-running query that then tried to read already-removed data was aborted as “snapshot too old”. (The old_snapshot_threshold feature was removed in PostgreSQL 17.)
When old_snapshot_threshold is set, VACUUM may remove old tuple versions that an aged snapshot still needs. If that snapshot then reads the affected data, the rows are gone, so PostgreSQL reports 72000 rather than returning wrong results.
Common causes
- Extremely long-running transactions/queries.
- Held cursors or idle-in-transaction sessions outliving the threshold.
- A reporting query running far longer than expected.
Relevant GUC parameters
| Parameter | Default | Effect |
|---|---|---|
old_snapshot_threshold |
-1 (disabled) | Max age a snapshot may be before its reads can fail with snapshot too old |
How to fix it
- Shorten or batch long-running queries/transactions.
- Avoid idle-in-transaction sessions; commit/rollback promptly.
- Increase
old_snapshot_threshold(or set -1 to disable) if long snapshots are required — at the cost of more bloat.
Related & next steps
Reference: PostgreSQL 18 — Resource Consumption configuration.
Thanks — noted. This helps keep the database accurate.