Database field guide · 38
PostgreSQL I/O Architecture
Buffers, read streams, writeback, WAL, and observability
Trace PostgreSQL I/O through shared buffers, operating-system cache, read streams, checkpoints, WAL ordering, and backend-visible statistics.
Franck Pachot7 chaptersPostgreSQL · I/O · shared buffers · checkpoints
Build the mental model before choosing the mechanism.
This minibook was AI-generated from Franck Pachot's archived blog posts. Links to the original articles are included for source context and verification.
01
A block crosses several layers
A PostgreSQL read can move through relation forks, the operating-system page cache, shared buffers, and a backend executor. A cache hit at one layer says nothing automatically about the others.
- Name the layer measured by each counter.
- Separate logical buffer access from physical reads.
- Retain block size and relation fork in low-level tests.
02
Shared buffers coordinate database pages
Backends pin and lock shared buffers while PostgreSQL tracks usage and dirty state. The buffer pool is a coordination and recovery structure, not merely a duplicate filesystem cache.
- Pin lifetime can limit replacement choices.
- Dirty buffers require ordered writeback.
- A larger pool is not universally a faster pool.
03
Read streams expose predictable access
Sequential, bitmap, and maintenance operations can combine adjacent blocks and prefetch future work. PostgreSQL 19 asynchronous reads add another execution method without changing SQL semantics.
- Compare issued blocks with consumed blocks.
- Measure combined-read size and queue depth.
- Keep random probes distinct from streaming scans.
04
Writes separate eviction from durability
Backends, background writing, and checkpoints can write dirty data pages, but WAL must be durable first. A data-page write is therefore different from a transaction commit flush.
- Observe backend and checkpoint writes separately.
- Track WAL write and sync time.
- Preserve write-ahead ordering in every tuning experiment.
05
Checkpoints shape bursts and recovery
Checkpoints bound crash-recovery work and cause dirty-page write pressure. Their cadence also affects full-page images, so changing checkpoint settings moves cost rather than deleting it.
- Correlate checkpoint timing with latency.
- Measure requested versus timed checkpoints.
- Include WAL volume and restart recovery in evaluation.
06
Diagnose pressure with layer-specific evidence
CPU saturation, memory pressure, storage latency, and excessive logical work can all look like slow I/O. Plans, pg_stat_io, buffer statistics, wait events, and operating-system metrics identify different boundaries.
- Start with one falsifiable bottleneck hypothesis.
- Compare latency, throughput, and queue depth.
- Do not tune storage to fix a cardinality explosion.
07
Field manual
Concrete mechanics, diagnostic evidence, and executable patterns to carry into a real system.
01
Read I/O by object and context
pg_stat_io separates backend type, object, context, operation counts, bytes, and timing where enabled. Interpret it alongside plans and operating-system data.
SELECT backend_type, object, context, reads, read_bytes, read_time,
writes, write_bytes, write_time, fsyncs, fsync_time
FROM pg_stat_io ORDER BY read_time + write_time DESC NULLS LAST;
02
Connect a plan to buffer work
Runtime plans expose shared, local, and temporary block activity. They quantify PostgreSQL buffer operations, not every storage-layer event.
EXPLAIN (ANALYZE, BUFFERS, WAL, SETTINGS, SUMMARY)
SELECT ...;
03
Observe checkpoint behavior
Modern PostgreSQL exposes checkpoint counts, write and sync duration, and buffers written. Correlate intervals with latency rather than reading cumulative values alone.
SELECT num_timed, num_requested, write_time, sync_time,
buffers_written, stats_reset
FROM pg_stat_checkpointer;
04
Separate WAL generation and sync
WAL records and bytes describe workload generation; writes, syncs, and timing describe the persistence path. Diagnose them as different stages.
SELECT wal_records, wal_fpi, wal_bytes, wal_write, wal_sync,
wal_write_time, wal_sync_time
FROM pg_stat_wal;
08
Source articles
Optional deep dives with the complete experiments and product-version context behind this guide.