2026-06-28
DRAM has a dirty secret: writes are slower than reads, not because the cells take longer, but because switching the bus from read mode to write mode (and back) costs cycles you'll never get back. A read-to-write turnaround on DDR5 burns roughly 7-15 ns of dead bus time. Do that on every write and you waste 30%+ of your memory bandwidth on direction-change overhead.
The memory controller's solution: don't drain writes when they arrive — hoard them in a write queue, then flush them in a burst. This is the write drain policy.
Two thresholds control it:
Between watermarks, reads have priority. The controller only pays the read→write→read turnaround penalty twice per drain cycle, instead of once per write. If you drain 24 writes in a burst, you've amortized the ~15 ns turnaround across all 24 — about 0.6 ns of overhead per write instead of 15.
Real-world example: a database doing a checkpoint flushes thousands of dirty pages. Without write batching, every flushed cache line would force a bus turnaround, and the checkpoint would crawl. With drain policy, the controller pools the writes and rips through them in a burst — checkpoint throughput can be 3-5× higher.
But there's a cost: reads issued during a drain burst sit and wait. If your latency-sensitive request lands right when the controller starts a write drain, you eat tens to hundreds of nanoseconds of unexpected stall. This is one reason why "tail latency" on memory-bound workloads gets ugly under write pressure — your p99 reads are the ones that arrived during a drain.
Rule of thumb: if your workload is read-dominated (>80% reads), drain policy is invisible. If it's write-heavy or mixed, every read has a probability roughly equal to (write queue occupancy / queue depth) of getting stuck behind a drain. A 50%-full write queue means roughly half your reads may hit drain stalls.
Some controllers expose tuning knobs (Intel's WrPreEmpt, AMD's write drain thresholds in BIOS) to bias the policy toward latency or bandwidth depending on workload.
