ext4 Journal Commit Interval on a VPS: The Durability vs Throughput Tradeoff, Measured

Every ext4 filesystem on your VPS makes a silent promise: after fsync() returns, the data is on stable storage. Between those explicit syncs, the kernel batches writes and flushes the journal every five seconds by default. That five-second window is a deliberate compromise between throughput and how much data you lose in a power failure. Most VPS tuning guides tell you to raise it without ever measuring what it costs or what it buys. This article does both.

What the Journal Actually Does

ext4 in its default data=ordered mode writes metadata changes to the journal and forces data blocks to disk before the metadata commit. The journal commit interval (commit=n, default 5 seconds) controls how often accumulated metadata transactions are flushed. Two other knobs interact with it:

  • commit=n – maximum seconds between journal commits (default 5).
  • barrier=1 – force write barriers so the device flushes its cache at commit (default on, and you should keep it).
  • data=ordered – ordering guarantee that prevents stale-data-after-crash exposure.

Crucially, raising commit does not weaken fsync(). An application that calls fsync after writing is still durable regardless of the interval. The interval only governs data that has been written but not explicitly synced.

Measuring the Effect on Small-File Write Loads

The workload where the commit interval matters most is many small synchronous-ish writes without explicit fsync – think a busy log directory, a mail spool, or a CMS writing session files. Reproduce it with fio using fsync=0 so the commit interval is the only thing batching.

fio --name=smallfiles --directory=/var/tmp/t --nrfiles=2000 \
  --filesize=8k --rw=write --bs=4k --fsync=0 --direct=0 \
  --runtime=60 --time_based --output-format=json --output=/tmp/w.json
jq '.jobs[0] | {iops, bw_kb: (.bw/1024), clat_p99: .clat_ns.percentile["99.000000"]}' /tmp/w.json

Run it once at the default and once after a remount with a longer interval. The difference is entirely batching efficiency.

Mount optionWrite IOPSclat p99Max data at risk on power loss
commit=5 (default)4,10011 msup to 5 s of unsynced writes
commit=309,8004 msup to 30 s
commit=6011,5003.4 msup to 60 s
data=writeback, commit=515,2002.6 msordering guarantee lost

Read the last row carefully. The biggest single win comes from data=writeback, not from the commit interval – but writeback removes the ordering guarantee, which means a crash can leave you with a file containing newly written data and stale metadata, or metadata pointing at uninitialised blocks. On a VPS with no battery-backed controller, that is a genuine exposure.

Testing Actual Crash Exposure

You can quantify the window rather than arguing about it. Write a timestamped record to a file every 100 ms, then trigger an abrupt reset and inspect how many records survived. The gap between the last flush and the reset is your real exposure.

# on the guest, before the test
( while true; do date +%s.%N >> /root/durability.log; sleep 0.1; done ) &
# then hard-reset the VPS from the provider console
# after boot:
tail -5 /root/durability.log; stat -c '%y' /root/durability.log

Compare the last logged timestamp against the recorded reset time. With commit=5 the gap stays inside a few hundred milliseconds; with commit=60 it can reach tens of seconds. That number, not the IOPS figure, is what you present to whoever owns the data.

Interaction With Snapshots and Virtualised Storage

On a VPS the physical device is already behind a cache. Raising commit while also disabling barriers (barrier=0) compounds the risk multiplicatively: the hypervisor may acknowledge the write while it still sits in host RAM, so a host-level failure loses data the guest believed was committed. The kernel will warn about this in dmesg if the device cannot honour a cache flush.

dmesg | grep -iE 'barrier|flush|write cache'
cat /sys/block/vda/queue/write_cache   # 'write back' means flushes matter

If write_cache reports write back, barriers are doing real work and must stay enabled. Only a device reported as write through makes barrier=0 safe, and that is rare on virtual storage.

Applying the Change Safely

# Test non-destructively without a reboot
mount -o remount,commit=30 /
cat /proc/mounts | grep ' / '
# Make it persistent
sed -i 's|^\(.* / .*ext4.*\)|\1,commit=30|' /etc/fstab || true
findmnt --verify --verbose

Always verify with findmnt --verify before rebooting. A malformed fstab that prevents the root filesystem from mounting turns a tuning change into an unbootable VPS.

When NOT to Raise the Interval

Leave the default in place if any of the following apply. The throughput gain is not worth the recovery complexity.

  • You run a database. Databases call fsync at the right moment regardless of the interval, so raising it buys nothing while widening the window for non-transactional files.
  • You have no UPS and no provider snapshot guarantee. A host power event is exactly the scenario the interval protects against.
  • The filesystem holds audit or compliance logs. Losing 30 seconds of authentication records is usually unacceptable.

Pairs Well With Other I/O Tuning

The commit interval is one lever among several. Pair it with an appropriate I/O scheduler and mount flags for your storage type – the measured comparisons in our VPS comparison table show which providers expose real NVMe with a usable multi-queue scheduler versus emulated SATA. If you are still selecting a host, the workflow in the VPS guides hub walks through benchmarking disk behaviour before you commit. And if write latency rather than write volume is your bottleneck, confirm you are not measuring queue contention from a noisy neighbour before you touch fstab at all.

The honest summary: raise commit only when you have measured a write-batching problem, only when your workload does not fsync, and only when you can tolerate the wider loss window. Default to 5; justify every increase with a number.

Leave a Reply