The Incident: Checkpoint Spikes and WAL Accumulation
TEXT
LOG: checkpoint complete: wrote 45212 buffers (86.3%); 0 WAL file(s) added, 0 removed, 184 recyle(s); write=182.431 s, sync=12.112 sDiagnosing I/O Bottlenecks and Buffer Cache Pressure
SQL
SELECT name, setting, unit, source FROM pg_settings
WHERE name IN ('checkpoint_completion_target', 'max_wal_size', 'min_wal_size', 'shared_buffers');| Parameter | Default Value | Tuned Production Value | Impact |
|---|---|---|---|
| 'checkpoint_completion_target' | '0.5' | '0.9' | Spreads I/O load across 90% of the window |
| 'max_wal_size' | '1GB' | '64GB' | Reduces checkpoint frequency during write peaks |
| 'vm.dirty_background_ratio' | '10' | '3' | Starts kernel background writeback earlier |
| 'vm.dirty_ratio' | '20' | '10' | Prevents application thread blocking on dirty pages |
Remediation and Configuration Tuning
1. Adjusting Checkpoint Spread
INI
# postgresql.conf adjustments
checkpoint_timeout = 30min
max_wal_size = 64GB
min_wal_size = 4GB
checkpoint_completion_target = 0.9
checkpoint_warning = 30s2. Linux Kernel Virtual Memory Tuning
BASH
# Apply runtime kernel memory adjustments
sysctl -w vm.dirty_background_ratio=3
sysctl -w vm.dirty_ratio=10
sysctl -w vm.swappiness=13. Evaluating Synchronous Commit Trade-offs
SQL
ALTER SYSTEM SET synchronous_commit = 'off';
SELECT pg_reload_conf();Monitoring WAL Generation Rate
SQL
SELECT
pg_wal_lsn_diff(pg_current_wal_lsn(), '0/00000000') AS total_wal_bytes,
date_trunc('minute', now()) AS observation_time;