checkpoint_timeout

Max time between checkpoints. Too short: I/O overhead. Too long: crash recovery takes minutes. 5min default balances both.

MEDIUM RISK
Safe first move

5min (default). Increase to 10-15min for write-heavy workloads if recovery time is acceptable.

Main risk

Too long (1h): crash recovery replays 930MB WAL (lab-captured). Too short (30s min): frequent I/O spikes. Default 5min: 53MB redo, 0.42s recovery.

Tier 1 — Lab-Proven — Measured behavior and safety boundaries are available below.

What We Observed

box

cl_ckpt_short/cl_ckpt_long (--memory=1g, PG 17.10), pgbench TPC-B scale 5, -c 4 -j 2 -T 30

short 30s

tps

1263.8

latency ms

3.16

stddev ms

2.118

note

min valid value=30s (5s rejected)

default 300s

tps

1092.2

latency ms

3.658

stddev ms

8.435

redo distance

30s

53MB (0.42s crash recovery)

3600s

930MB (much longer crash recovery)

source

formula curve

# FIXED WORK: -t 40000 -c 4 = 160000 txns per setting; max_wal_size=16GB (time-driven); scale=50; img=postgres:17

checkpoint_timeout  tps  num_timed  log_timed  buffers_written  wal_records  wal_fpi  wal_MB
30s                 1031.750729  5          5          19777            1047974      179217   1417.2
60s                 873.660878  3          3          5696             1048766      147971   1187.7
120s                808.770060  1          1          947              1047752      127656   1036.0
300s                1596.810068  0          0          0                1049988      84034    710.6

crash evidence

================= checkpoint_timeout=30s (SHORT timeout -> small redo distance -> FAST recovery) ================= -- loading WAL for 240s with NO checkpoint allowed (timeout=30s, max_wal_size=16GB) -- redo distance since last checkpoint = 53.0 MB | timed checkpoints during run = 8 -- SIGKILL (crash) -- -- recovery log (literal) --

2026-06-19 15:30:46.656 UTC [55] LOG:  database system is ready to accept connections
2026-06-19 15:30:46.971 UTC [1] LOG:  database system is ready to accept connections
2026-06-19 15:34:59.429 UTC [29] LOG:  database system was not properly shut down; automatic recovery in progress
2026-06-19 15:34:59.432 UTC [29] LOG:  redo starts at 0/B7D98E58
2026-06-19 15:34:59.856 UTC [29] LOG:  invalid record length at 0/C4D9A8D0: expected at least 24, got 0
2026-06-19 15:34:59.856 UTC [29] LOG:  redo done at 0/C4D9A8A8 system usage: CPU: user: 0.26 s, system: 0.14 s, elapsed: 0.42 s
2026-06-19 15:35:00.232 UTC [1] LOG:  database system is ready to accept connections

================= checkpoint_timeout=3600s (LONG timeout (1h) -> large redo distance -> SLOW recovery) ================= -- loading WAL for 240s with NO checkpoint allowed (timeout=3600s, max_wal_size=16GB) -- redo distance since last checkpoint = 930.6 MB | timed checkpoints during run = 0 -- SIGKILL (crash) -- -- recovery log (literal) --

2026-06-19 15:35:03.122 UTC [56] LOG:  database system is ready to accept connections
2026-06-19 15:35:03.439 UTC [1] LOG:  database system is ready to accept connections
2026-06-19 15:39:15.061 UTC [29] LOG:  database system was not properly shut down; automatic recovery in progress
2026-06-19 15:39:15.065 UTC [29] LOG:  redo starts at 0/27EEE130
2026-06-19 15:39:20.320 UTC [29] LOG:  invalid record length at 0/62188D90: expected at least 24, got 0
2026-06-19 15:39:20.320 UTC [29] LOG:  redo done at 0/62188D68 system usage: CPU: user: 2.79 s, system: 2.42 s, elapsed: 5.25 s
2026-06-19 15:39:21.058 UTC [1] LOG:  database system is ready to accept connections

== teardown ==

Reproduced Danger

Sizing / Safe Range

Workload Guidance

Unlock Incident Pro

The free sections tell you what to do. Pro is the measured proof — the exact failure signature, safe-ceiling formula, and per-workload defaults, each captured on real PG 14–18 runs.

  • Reproduced Danger
  • Sizing / Safe Range
  • Workload Guidance
Unlock Incident Pro

checkpoint_timeout is the maximum wall-clock time PostgreSQL will let pass between automatic checkpoints. A checkpoint is the point at which all dirty shared buffers are flushed to the data files and a record is written to WAL marking 'everything before here is safely on disk' — so on crash recovery, replay only has to start from the last completed checkpoint's redo point, not the beginning of time. The checkpointer fires a checkpoint when EITHER checkpoint_timeout elapses OR max_wal_size of WAL has been written since the last one, whichever comes first. checkpoint_timeout is the TIME lever (max_wal_size is the VOLUME lever). It defaults to 300 s (5 minutes). The value sits on a genuine two-sided tradeoff: a SHORTER timeout means more frequent checkpoints, which keeps crash-recovery fast (less WAL to replay) but amplifies steady-state WAL writes — because full_page_writes re-arms at every checkpoint, so the first modification to each page after a checkpoint emits a full-page image (FPI) into WAL. A LONGER timeout means fewer checkpoints, less FPI write amplification, and lower steady-state I/O, but a larger redo distance and therefore a longer crash recovery (longer outage). This lab MEASURED both halves of that tradeoff.

name

checkpoint_timeout

setting default

300

unit

s (300 s = 5 min default)

vartype

integer

category

Write-Ahead Log / Checkpoints

context

sighup

min val

30

max val

86400

boot val

300

reset val

300

pending restart

false

short desc

Sets the maximum time between automatic WAL checkpoints.

ground truth note

Captured literally from pg_settings on PG 14-18 (-18) on 2026-06-19. setting=300, boot_val=300, reset_val=300 (= 5 minutes) on EVERY version — default_changed=false, boot_fallback_changed=false. context=sighup (reload, no restart), vartype=integer, unit=s, min_val=30 s, max_val=86400 s (24 h) identical on all five versions. The 5-minute default and every surrounding fact are unchanged 14→18.

Common Pitfalls

  • Raising checkpoint_timeout without raising max_wal_size — the VOLUME trigger fires first and the timeout change does nothing (proven; the lab held max_wal_size=16GB to avoid exactly this).
  • Setting it very high (e.g. 1h) to save WAL — redo distance and crash-recovery time balloon (measured: 930.6 MB redo → 5.25 s recovery vs 53.0 MB → 0.42 s), blowing your RTO; far worse on production-sized WAL and slow storage.
  • Assuming shorter is always safer — a short timeout amplifies steady-state WAL (~2× the WAL for the same work at 30 s vs 300 s here) and increases checkpoint I/O.
  • Confusing checkpoint_timeout (time trigger) with max_wal_size (volume trigger) — checkpoints fire on whichever comes first; you must reason about both.
  • Forgetting it is sighup — ALTER SYSTEM SET + SELECT pg_reload_conf is enough; no restart needed (and a session cannot set it for itself).
  • Disabling full_page_writes to cut the FPI cost — that risks torn-page corruption on crash; use wal_compression instead if you need smaller FPIs.
  • Benchmarking the WAL effect with a fixed-TIME load (pgbench -T) — faster settings do more work and the FPI signal is swamped; you MUST use fixed WORK (pgbench -t). This lab's first run failed exactly this way.

Evidence and References

  • PostgreSQL 18 docs — Write Ahead Log / Checkpoints: checkpoint_timeout, max_wal_size, checkpoint_completion_target (runtime-config-wal.html)
  • PostgreSQL 18 docs — full_page_writes: full pages written to WAL on first modification after a checkpoint (runtime-config-wal.html)
  • PostgreSQL docs — WAL Internals / Reliability: crash recovery replays WAL starting from the last checkpoint's redo point
  • PostgreSQL docs — The Cumulative Statistics System: pg_stat_wal (wal_fpi, wal_bytes, wal_records), pg_stat_checkpointer (num_timed) — the counters this lab measured and cross-checked against log_checkpoints
  • Captured live on PG 14-18 (-18) ground truth + postgres:17 effect/crash labs (cl_ckpt, cl_ckptcrash), 2026-06-19, sev1db-config-eval

Technical Reference

Category
Write-Ahead Log / Checkpoints
Type
integer (s (300 s = 5 min default))
Blast radius
cluster
Severity
Moderate
Context
sighup
Versions
14, 15, 16, 17, 18
Reviewed
2026-06-19

Severity scale: 1 Minimal · 2 Low · 3 Moderate · 4 High · 5 Critical.

Keep going

Related & next steps

Concepts on this page

Parameters to check