Every few minutes a production database shows a burst of write I/O with latency spikes across unrelated queries, and the bursts line up with its checkpoints. Explain the mechanism and how you would smooth it out.
answer
- dirty pages accumulate, then random writes all at once
- random writes + queue saturation -> reads suffer too
- spread over 80-90% of the interval
- background writer trickles, checkpoint finds less
- fsync can re-bunch nicely paced writes
basics
~20 sDirty pages accumulate between checkpoints and are then flushed in a burst of random writes that saturates the device, so every query queues behind it. Smooth it by spreading the flush over most of the interval, letting a background writer trickle pages out continuously, and reducing dirty-page accumulation.
solid answer
~60 sBetween checkpoints, updates accumulate as dirty pages in the buffer pool - deliberately, since that lets many changes to a page coalesce into one write. When the checkpoint runs it must push all of that to disk, and those writes are **random** (scattered across the data files) rather than sequential like the log. If the engine issues them as fast as it can, the device's queue fills, service time for *every* I/O rises, and unrelated queries that need a single page read wait behind the flood. The visible signature is periodic, correlated with checkpoint start, and it hits reads as well as writes. Remedies, in order of preference: 1. **Pace the flush** - spread it over a large fraction of the interval so it becomes a hum rather than a spike. 2. **Strengthen the background writer** so pages are trickled out continuously and the checkpoint finds less work. 3. **Reduce the amount to flush**: a smaller pool or shorter interval lowers per-checkpoint volume, at the cost of more repeated writes. 4. Check the OS side - a large kernel writeback cache can convert paced writes back into a burst at fsync time.
go deeper
Know that dirty pages pile up and are written at checkpoints, and that this write burst can slow other queries.
Explain the random-write and queueing mechanism, and name pacing plus the background writer as the standard mitigations.
Diagnose from checkpoint statistics and device metrics, distinguish timer-triggered from volume-triggered checkpoints, and reason about each lever's side effects including log volume and recovery time.
Treat it as an I/O budget and SLO problem: latency percentiles versus total write amplification, device and log/data separation, index count as a write multiplier, and how far tuning can go before capacity is the real answer.
## The mechanism Deferred page writes are the whole point of a write-ahead-logging engine: a commit writes a small sequential log record, and the modified page stays dirty in the buffer pool absorbing further updates. The saving is real - a hot page updated a thousand times can cost one physical write. The bill arrives at the checkpoint. All those dirty pages must reach the data files, and unlike log writes they are **random**: scattered block addresses across files, each one an independent seek-equivalent operation. Three effects compound: - **Volume**: on a large buffer pool with a write-heavy workload, gigabytes of dirty data may be pending. - **Randomness**: random writes are the worst pattern for almost any device, and on SSDs they also drive write amplification inside the flash translation layer, sometimes triggering garbage collection whose latency the database cannot see or control. - **Queueing**: once the device queue is saturated, *every* I/O behind it inherits the queue delay. A trivial point query that needs one page read now waits milliseconds instead of microseconds. This is why the symptom appears on reads and on queries that write nothing. A secondary effect: on some systems the checkpoint's fsync of a data file forces out everything the kernel had buffered for that file, so even a nicely paced sequence of writes collapses into one enormous synchronous flush at fsync time. Paced writes plus an unpaced fsync still produces a spike. ## Confirming the diagnosis Before tuning, establish the correlation properly: - Plot device write throughput, queue depth, and service time against checkpoint start/end timestamps from the engine's log. The bursts should begin at checkpoint start. - Look at the per-checkpoint statistics engines expose: how many buffers were written, how long the write phase and the sync phase took, and whether checkpoints were triggered by the timer or by log volume. - A checkpoint triggered by log volume rather than the timer is a strong signal: the system is dirtying faster than the interval assumed, and the checkpoint is running more often and more violently than configured. - Confirm the latency spike hits queries that are not writing - that distinguishes device-queue saturation from lock contention. ## Smoothing it **Spread the writes across the interval.** Every mature engine can pace checkpoint I/O to complete over some fraction of the interval - say 80-90% - rather than as fast as possible. The same bytes are written; they are just dribbled out. This is nearly always the first and highest-value change, and its cost is that a checkpoint is almost always in progress. **Let the background writer do more.** A background writer continuously flushes pages that are likely eviction candidates, independently of checkpoints. Tuned up, it keeps the dirty fraction of the pool low, so each checkpoint finds fewer pages to write and the burst shrinks at the source. Tuned too aggressively it writes pages that would have been re-dirtied anyway, wasting I/O - the balance is workload-specific. **Change how much accumulates.** Two levers, both double-edged: - A *shorter* interval means less dirty data per checkpoint (smaller spikes, faster recovery) but more total writes, because pages get less time to coalesce updates - and, where full-page images are used, substantially more log volume since each checkpoint resets every page to 'first touch'. - A *smaller buffer pool* caps how much can be dirty at once, but costs read hit rate. Rarely the right lever. **Tune the OS writeback.** Lower the kernel's dirty-data thresholds so it starts writing back earlier and holds less pending at fsync time. This converts one big synchronous flush into continuous background writeback. **Provide more I/O capacity.** Faster or separate devices, and in particular putting the log on separate storage from the data files, so the checkpoint's random data writes cannot delay the sequential log writes that commits actually wait on. This is often the single most effective structural change on a write-heavy system. **Reduce the write volume itself.** Fewer, better-batched updates; avoiding hot-row update patterns; reconsidering indexes, since every index on a table multiplies the pages a single row update dirties. ## The tradeoff to state explicitly Smoothing does not reduce total work; it redistributes it. Pacing trades a short violent spike for continuous moderate load - good for latency percentiles, and the right call when the SLO is about p99. Shortening the interval trades total write volume for shorter recovery and smaller spikes. The one thing not to do is chase a smoother graph by making checkpoints so frequent that write amplification and log volume become the new bottleneck.
- Why do checkpoint write bursts slow down read-only queries that touch none of the affected tables?The bottleneck is the shared storage device, not the data. Once the write flood fills the device queue, every subsequent I/O request - including a single-page read for an unrelated query - waits behind it, so service times rise across the board. This is why the symptom appears system-wide and why separating log and data storage, or adding I/O capacity, helps queries that have nothing to do with the writes.
- Your engine reports that checkpoints are being triggered by log volume rather than by the configured time interval. What does that tell you?The workload is generating changes faster than the interval was sized for, so the volume-based trigger fires first and checkpoints run more often than configured. That means both more frequent flush bursts and, where full-page images are used, more log volume, which feeds back into triggering again. The response is to look at the write rate itself and at the volume threshold together, rather than only adjusting the timer.
- Would enlarging the buffer pool help or hurt this symptom?It usually helps reads and hurts this particular symptom. A larger pool lets more dirty pages accumulate between checkpoints, so each checkpoint has more to flush and the burst grows. The proper fixes are pacing and background writing, which change how the same volume is delivered, rather than trading away read performance by shrinking the pool.
saying these in an interview costs you the question
- Concluding it is lock contention without checking whether read-only queries are affected
- Recommending 'checkpoint less often' as an unqualified fix - larger, rarer spikes and slower recovery
- Assuming spreading checkpoint writes reduces total I/O rather than redistributing it
- Forgetting that fsync can re-bunch paced writes into a single stall
- Ignoring that each additional index multiplies the pages one row update dirties