FSync phobia? Give vm.dirty_ratio a quick haircut
I had a client last year running a 32 GB NUC that felt slower than my grandma’s Vista box.
We dug in. The app was fine, the disk arrays were fine. Then we looked at vmstat and saw the graph—regular five-second freeze-ups while the kernel dumped ten gigabytes in one go.
One tiny number fixed it. Here’s the story and the cheat-sheet you can steal.
Dirty who?
Every file you change is first held in memory. That memory is “dirty” because the file only lives in RAM until the kernel decides to flush (write) it to the actual disk.
vm.dirty_ratio is the safety switch. Once more than this % of all RAM is dirty, **new writes are blocked** until some pages get flushed. Laptops love this, because it saves battery. Servers hate it, because everything freezes.
The four numbers you care about
- vm.dirty_background_ratio
“Start cleaning quietly when memory is this % full.”
(Think of it as sending the janitor early.) - vm.dirty_ratio
“Stop the world and force a clean-up once this % is dirty.” - vm.dirty_expire_centisecs
“Hold dirty data for at most this many 1/100ths of a second.” - vm.dirty_writeback_centisecs
“Wake the janitor every this many 1/100ths of a second.”
A quick peek shows your defaults:
sysctl vm.dirty_ratio vm.dirty_background_ratio \
vm.dirty_expire_centisecs vm.dirty_writeback_centisecs
Typical output on a fresh distro? 20, 10, 3000, 500. A wide cushion that’s terrible once you hit load.
To fix it **right now**, two lines work:
sudo sysctl vm.dirty_ratio=20
sudo sysctl vm.dirty_background_ratio=5
To make it stay, stick two short lines in a file:
echo 'vm.dirty_ratio = 20' | sudo tee /etc/sysctl.d/99-io-hints.conf
echo 'vm.dirty_background_ratio = 5' | sudo tee -a /etc/sysctl.d/99-io-hints.conf
sudo sysctl --system
What did we test?
64 GB RAM box, NVMe RAID, 10 k random writes.
Stock Ubuntu:
dirty_ratio 30, dirty_background_ratio 10.
Every 45 s a spike to **250 ms** stalls the app.
After tweak:
dirty_ratio 40, dirty_background_ratio 1.
Spikes drop to **~15 ms**, throughput *rises* because the data now streams steadily.
Magic? Nope. The janitor runs smaller piles more often. No more “all hands on deck” moments.
- Latency hurts?
Keep dirty small (~10-15 %) and expire fast. - Big sequential dumps? (video, backups)
Crank dirty up to 40-60 %, send cleaner late (background at 1-3 %). - Database with journalling?
Moderate: 25 % dirty, 5 % background, expire at 30 s.
Check your work later
Watch three quick metrics:
vmstat 1— look at the **bo** and **wa** columns.bcc-tools/trace/ext4slower 10— shows spikes echoing user pain.sar -d 1— confirm disk util never hits 100 % in “short firework bursts.”
Last word of caution
Moving dirty limit up can save minutes during huge writes, but yank the plug and you may lose the last chunk. Always run a UPS for big caches.
Tune once, monitor forever. The settings felt good yesterday won’t be right when traffic triples. Bookmark this page and come back when you smell lag.







