Cookbook recipe

bgwriter_maxwritten_clean Counter Rising

Applies to PostgreSQL 13–17 Last reviewed May 2026 Grounded in source
Estimated investigation4 min

Scenario

Scenario A DBA notices that the buffers_maxwritten_clean counter in pg_stat_bgwriter is steadily rising. This counter increments every time the background writer stops a cleaning scan because it hit bgwriter_lru_maxpages. It means the bgwriter is being throttled…

Investigation Path

Scenario

A DBA notices that the buffers_maxwritten_clean counter in pg_stat_bgwriter is steadily rising. This counter increments every time the background writer stops a cleaning scan because it hit bgwriter_lru_maxpages. It means the bgwriter is being throttled — it cannot keep up with dirty buffer production, so checkpoints must clean buffers themselves, causing checkpoint I/O spikes. The root cause: bgwriter_lru_maxpages is set too low (default 100) for a write-heavy workload.

How to Identify

Conditions:

  • buffers_maxwritten_clean in pg_stat_bgwriter is non-zero and rising
  • I/O spikes correlate with checkpoint timing (buffers_checkpoint rises sharply)
  • bgwriter_lru_maxpages = 100 (default) — bgwriter stops after 100 pages per round
  • Disk write latency increases during checkpoint periods
  • buffers_clean (written by bgwriter) is much lower than buffers_checkpoint

Analysis Steps

-- Check bgwriter statistics:
SELECT
    buffers_checkpoint,
    buffers_clean,
    maxwritten_clean,
    buffers_backend,
    buffers_backend_fsync,
    buffers_alloc,
    stats_reset
FROM pg_stat_bgwriter;
-- buffers_checkpoint >> buffers_clean = bgwriter not keeping up
-- maxwritten_clean > 0 = bgwriter being throttled (hit lru_maxpages limit)
-- buffers_backend > 0 = backends writing their own buffers (bad — means shared_buffers pressure)

-- Check bgwriter settings:
SELECT name, setting, unit
FROM pg_settings
WHERE name LIKE 'bgwriter%'
ORDER BY name;
-- bgwriter_lru_maxpages = 100 (default) — increase if maxwritten_clean is rising
-- bgwriter_lru_multiplier = 2.0 (default) — multiplier for anticipated need
-- bgwriter_delay = 200ms (default) — sleep between bgwriter rounds

Pitfalls

  • buffers_maxwritten_clean rising is a symptom, not the root cause — the root cause is that the workload produces dirty buffers faster than bgwriter can flush them.
  • Increasing bgwriter_lru_maxpages increases bgwriter I/O — on already I/O-saturated systems this can make things worse. Tune in small increments.
  • buffers_backend > 0 means backends are writing their own buffers instead of finding clean ones — this blocks foreground queries. It indicates shared_buffers is too small or bgwriter is severely under-configured.
  • buffers_backend_fsync > 0 is critical: backends had to do their own fsync (data integrity path) — this means the checkpoint process was also overwhelmed.
  • pg_stat_bgwriter is cumulative since stats_reset. Always compare deltas over time, not absolute values.

Resolution Approach

Increase bgwriter_lru_maxpages to allow bgwriter to write more pages per round. Increase bgwriter_lru_multiplier slightly to scan more buffer candidates. Also check checkpoint_completion_target (should be 0.9) and max_wal_size to spread checkpoint I/O.

This is a Pro lesson

Get every Learning Pathway and cookbook recipe — grounded in PostgreSQL source code, with diagnostics, fixes, and prevention for each topic.

Continue this lesson to learn:

  • Mitigation Actions
  • All 36 Learning Pathway lessons
  • 170+ cookbook recipes
  • Source-grounded diagnostics & fixes

Secure checkout Cancel anytime Source-grounded

Career Impact

This scenario builds production judgment and operational confidence under pressure.

Open Career Dashboard →

Keep going

Related & next steps

Was this helpful?

← All cookbook recipes