# old_snapshot_threshold

> old_snapshot_threshold — Time before a snapshot is too old to read pages changed after the snapshot was taken. Observed in PG9.6–16; its last measured boot default is -1 min in PG16, with postmaster context. It was removed in PG17.
---

> [!NOTE]
> **Fact — official short description:** “Time before a snapshot is too old to read pages changed after the snapshot was taken.”

## Identity {#identity}

| Field | Value | Meaning |
| --- | --- | --- |
| Type | `integer` | Upstream pg_settings type |
| Context | `postmaster` | Requires a server restart |
| Unit | `min` | Raw unit |
| Range | `-1` – `86400` | Raw limits in the last observed version |
| Enum values | — | — for non-enum types |
| Category | Resource Usage / Asynchronous Behavior | Upstream classification |
| Latest boot value | `-1` | -1 min |
{.fields meta="-"}

## Lifecycle {#lifecycle}

| Fact | Value |
| --- | --- |
| First observed | PG9.6 |
| Present in | PG9.6–16 |
| Removed in | PG17 |
| Introduction commit | [`848ef42bb8c7`](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=848ef42bb8c7909c9d7baa38178d4a209906e7c1) — Add the "snapshot too old" feature |
| Commit date | 2016-04-08 |
| Discussion | — |

## Default history {#default-history}

| Versions | Raw `boot_val` | Unit | Human value |
| --- | --- | --- | --- |
| PG9.6–16 | `-1` | `min` | -1 min |
{.full-width caption="Measured PG9.0–19 Beta 3 boot defaults"}

## How it works {#mechanism}

old_snapshot_threshold, available through PG16 and removed in PG17, marked snapshots as too old after a configured time so page pruning could proceed more aggressively. A later read could fail with snapshot-too-old rather than return a historical page image.

It was not a transaction timeout: the transaction could continue until it touched data whose old versions had been removed. The feature required startup-time tracking overhead even before a failure appeared.

It did not replace vacuum discipline or prevent all bloat. Because the feature was removed, migration must not carry the parameter into PG17+ and applications must not depend on its error behavior. Its postmaster context fixes the value at server start; changing it requires a restart.

## Tuning advice {#tuning-advice}

> [!TIP]
> **Advice.** These are workload-specific starting points and must be validated with measurements.

| Workload | Guidance |
| --- | --- |
| OLTP | Do not tune old_snapshot_threshold on current PostgreSQL: remove it from upgrade targets and use the current replacement behavior described above. Retain it only when reproducing the historical version. |
| OLAP | Do not carry old_snapshot_threshold into a modern analytical cluster. Benchmark the supported current mechanisms instead of trying to emulate a removed implementation detail. |
| Small nodes | Delete old_snapshot_threshold during version migration; an unknown-parameter startup failure is more likely than a benefit. Historical test instances should keep the old upstream default. |
{.full-width}

## Pigsty {#pigsty}

Values use the fixed 8-vCPU, 32-GiB, 100-GiB SSD fixture and render the current Pigsty templates for PG16; this does not assert current Pigsty support for that historical or beta release.

| Template | Effective value | Versus upstream boot | Source expression |
| --- | --- | --- | --- |
| OLTP | Unmodified | — | — |
| OLAP | Unmodified | — | — |
| CRIT | Unmodified | — | — |
| TINY | Unmodified | — | — |
{.full-width}

> [!CAUTION]
> **Advice — pending human review.** Fact from the current Pigsty template projection: OLTP: PG9.6–16 unmodified; OLAP: PG9.6–16 unmodified; CRIT: PG9.6–16 unmodified; TINY: PG9.6–16 unmodified. No Pigsty-specific rationale is inferred from an absent override.

## Common pitfalls {#common-pitfalls}

- Changing old_snapshot_threshold without applying its documented unit and configuration context.
- Optimizing an isolated benchmark while ignoring concurrent aggregate resource use.
- Assuming a configured value guarantees operating-system or storage behavior.
- Failing to retest startup, failover, and workload latency after the change.

## Related parameters {#related-parameters}

[`vacuum_defer_cleanup_age`](/parameters/vacuum-defer-cleanup-age/) · [`autovacuum`](/parameters/autovacuum/) · [`hot_standby_feedback`](/parameters/hot-standby-feedback/) · [`idle_in_transaction_session_timeout`](/parameters/idle-in-transaction-session-timeout/)

## References {#references}

- [PostgreSQL 16 — old_snapshot_threshold](https://www.postgresql.org/docs/16/runtime-config-resource.html#GUC-OLD-SNAPSHOT-THRESHOLD)
- [Machine-readable GUC export](/data/guc.jsonl)
