PG-R12performanceConfidence: 80%Reversibility: safe

Checkpoint Frequency Too High

System views: pg_stat_bgwriter

Overview

Postgres writes all dirty shared_buffers pages to disk at each checkpoint. Checkpoints happen on a schedule (checkpoint_timeout, default 5 min) or when WAL fills max_wal_size. Frequent checkpoints—especially those triggered by WAL fill (checkpoints_req) rather than by time—cause bursty I/O that slows all concurrent write activity and can saturate disk bandwidth.

The signal is checkpoints_req / (checkpoints_timed + checkpoints_req) > 50%: more than half of checkpoints are forced, meaning the write rate is exceeding the WAL size budget. The standard fix is to increase max_wal_size (typically to 2–8 GB depending on disk speed), which allows Postgres to spread checkpoints over more WAL and reduces their frequency.

Detection SQL

Run this query with a read-only role. No writes, no locks.

-- Ratio of requested vs timed checkpoints; high requested% = WAL being filled too fast
SELECT
  checkpoints_timed,
  checkpoints_req,
  round(
    checkpoints_req::numeric / NULLIF(checkpoints_timed + checkpoints_req, 0) * 100,
    1
  )                                     AS req_checkpoint_pct,
  checkpoint_write_time,
  checkpoint_sync_time,
  pg_size_pretty(
    (buffers_checkpoint + buffers_clean + buffers_backend)::bigint * 8192
  )                                     AS total_written,
  maxwritten_clean,
  buffers_backend_fsync
FROM pg_stat_bgwriter;

Fix SQL

Replace placeholders in <angle brackets> with values from the detection output before running.

-- Increase max_wal_size to reduce checkpoint frequency (requires reload, not restart)
ALTER SYSTEM SET max_wal_size = '4GB';
SELECT pg_reload_conf();

-- Also tune checkpoint_completion_target to spread I/O
ALTER SYSTEM SET checkpoint_completion_target = 0.9;
SELECT pg_reload_conf();

Worked example

After a product launch, write throughput doubled. checkpoints_req jumped to 78% of all checkpoints. checkpoint_sync_time averaged 12 seconds per checkpoint, occurring every 90 seconds instead of the 5-minute default. Setting max_wal_size = '4GB' and checkpoint_completion_target = 0.9 dropped checkpoint frequency to every 4 minutes and sync time to under 2 seconds.

Common false positives

  • Systems with very fast NVMe storage may tolerate high checkpoint frequency without performance impact — correlate with disk latency metrics before tuning.
  • Immediately after a bulk load (COPY, large batch INSERT), checkpoints_req spikes transiently — this is expected and not a sustained issue.

Check for checkpoint frequency too high across your whole estate.

Insightral runs this rule — and 98 more — continuously inside your private cloud, with read-only credentials and nothing leaving your network.

Request early access

Last updated: 2026-05-13 · View all published rules