Control panels

Optimizing disk I/O on a VPS: tuning mount options and swap

Reduce disk latency on a Linux VPS by choosing the right I/O scheduler, trimming write-heavy mount options, and tuning swap and dirty-page settings.

AdvancedLinux server6 min read

To optimize disk I/O on a Linux VPS you change three things: the kernel I/O scheduler for the virtual disk, the mount options your filesystem boots with, and the memory/swap settings that decide when writes hit the disk. This guide walks through measuring your current performance, applying each change safely, and verifying the result — with a rollback path at every step.

Most slow-VPS complaints are not "the disk is slow". They are the kernel writing too eagerly, filesystems recording access times nobody reads, or swap thrashing during a memory spike. Fixing that is a configuration job, not a hardware upgrade.

Before you start

You need root (or a sudo user) on a Linux VPS running Ubuntu 22.04/24.04, Debian 12 or AlmaLinux/Rocky 8–9.

Warning: Every change in this guide touches /etc/fstab, kernel parameters or swap. A bad fstab entry can stop the server from booting. Keep the browser console in your VPS provider's control panel open in another tab, and never reboot until findmnt --verify passes.

Gather the facts first:

  • Confirm what disk you actually have. A virtio or NVMe device behaves differently from emulated SATA.
  • Note free space. Anything below roughly 10–15% full slows writes on most filesystems.
  • Know your memory size — swap tuning depends on it.
Bash
lsblk -o NAME,SIZE,TYPE,MOUNTPOINT,ROTA
df -hT
findmnt --verify
free -h
swapon --show

ROTA 0 means the kernel sees a non-rotational (SSD-backed) device. findmnt --verify should print "Success, no errors or warnings detected" before you touch anything.

Measure the current disk I/O on your VPS

Numbers first, opinions later. Install fio and run one direct-write test against a scratch file.

Bash
sudo apt update && sudo apt install -y fio    # Debian/Ubuntu
sudo dnf install -y fio                        # AlmaLinux/Rocky
Bash
fio --name=randwrite --ioengine=libaio --iodepth=16 --rw=randwrite \
  --bs=4k --direct=1 --size=512M --numjobs=1 --runtime=60 \
  --group_reporting --filename=/var/tmp/fio-test

Warning: fio writes real data to /var/tmp/fio-test. Make sure the partition has at least 1 GB free, and delete the file when you are finished.

Record the write: IOPS and clat figures. Run the same command again after your changes so you compare like with like. A quick alternative for latency-sensitive databases is ioping, which shows per-request delay rather than throughput.

Set the I/O scheduler

Bash
cat /sys/block/vda/queue/scheduler
cat /sys/block/vda/queue/rotational

For SSD-backed virtual disks the usual choices are:

  • none — no reordering, lowest overhead, best on fast NVMe.
  • mq-deadline — adds bounded latency for every request, good for busy multi-tenant hosts.
  • kyber — lightweight queueing for fast devices, available on recent kernels.

Avoid bfq on a VPS unless you specifically need fairness between processes; it costs CPU.

Make it persistent with a udev rule so it survives reboots without editing a bootloader:

INI
# /etc/udev/rules.d/60-io-scheduler.rules
ACTION=="add|change", KERNEL=="vd*", ATTR{queue/scheduler}="mq-deadline"
ACTION=="add|change", KERNEL=="sd*", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="none"
ACTION=="add|change", KERNEL=="nvme*", ATTR{queue/scheduler}="none"

Apply and confirm:

Bash
sudo udevadm control --reload && sudo udevadm trigger
cat /sys/block/vda/queue/scheduler

Tune mount options in /etc/fstab

Open /etc/fstab and edit only the options field (the fourth column). Keep the UUID exactly as it is.

Bash
sudo cp /etc/fstab /etc/fstab.bak
sudo findmnt --verify

Two commonly useful changes:

  • noatime — stop recording every file read. On busy web servers this removes a large share of small writes with no downside for normal workloads. Use relatime instead if some tool depends on access times.
  • errors=remount-ro (ext4) — mount read-only after a filesystem error instead of carrying on and corrupting more data.
# /etc/fstab (ext4 example)
UUID=0d5a1f5e-1d3e-4e6a-9c1a-2f0b7c9d4e11 / ext4 defaults,noatime,errors=remount-ro 0 1

For XFS, noatime,nodiratime and optional logbsize=64k are the usual starting points. For discard, prefer the weekly fstrim timer over continuous TRIM — online discard can make deletes noticeably slower on loaded virtual disks.

Bash
sudo systemctl enable --now fstrim.timer
systemctl list-timers fstrim.timer

Test the entry without rebooting:

Bash
sudo findmnt --verify --verbose
sudo mount -o remount / && findmnt /

Warning: If findmnt --verify reports errors, fix /etc/fstab before rebooting. A malformed entry can drop the server into an emergency shell that only your VPS provider's console can reach.

Tune kernel dirty-page and cache settings

The kernel buffers writes in RAM and flushes them later. If the flush thresholds are too high, a memory-heavy process can trigger a long stall while gigabytes are written at once.

INI
# /etc/sysctl.d/99-io-tuning.conf
vm.swappiness = 10
vm.dirty_background_ratio = 5
vm.dirty_ratio = 15
vm.vfs_cache_pressure = 50
  • dirty_background_ratio — start background flushing at this percentage of RAM.
  • dirty_ratio — processes block once dirty data reaches this percentage.
  • vfs_cache_pressure — lower values keep dentry/inode cache longer, which helps file-heavy workloads.
  • swappiness — how aggressively anonymous pages move to swap.

Apply without a reboot:

Bash
sudo sysctl --system
sysctl vm.swappiness vm.dirty_ratio

If the VPS is small (1–2 GB RAM), consider absolute limits instead of ratios, for example vm.dirty_bytes = 268435456 and vm.dirty_background_bytes = 67108864, so a single large write cannot occupy a quarter of memory.

Tune swap for a VPS

Swap does not make a disk faster, but the wrong swap setup makes I/O look slow. Check what you have:

Bash
swapon --show
cat /proc/swaps

If there is no swap at all, add a swap file before tuning anything else — see Add a swap file on a Linux VPS.

For a VPS with enough RAM, vm.swappiness = 10 keeps the kernel from paging idle services out. Do not set it to 0 unless you have a specific reason; that removes the safety valve and can turn a memory spike into an OOM kill.

Tip: On hosts where swap lives on the same virtual disk as your data, heavy swap use competes directly with database I/O. Watch si/so in vmstat 1 — sustained non-zero values mean memory pressure, not a disk problem.

Check it works

Bash
findmnt / | grep -o 'noatime'
cat /sys/block/vda/queue/scheduler
sysctl vm.swappiness vm.dirty_ratio
systemctl is-active fstrim.timer
free -h && swapon --show

Then re-run the same fio command you used for the baseline and compare IOPS and completion latency. Remove the test file:

Bash
rm -f /var/tmp/fio-test

Finally, reboot once during a maintenance window and confirm everything came back: mount, sysctl, scheduler and swap settings should all match what you configured.

Troubleshooting

  • Server does not boot after editing fstab — a syntax error or wrong UUID. Connect through your VPS provider's console, run mount -o remount,rw /, restore /etc/fstab.bak, fix the entry and run findmnt --verify before rebooting again.
  • "cannot remount /dev/vda1 read-write, is write-protected" — ext4 hit an error and remounted read-only because of errors=remount-ro. Check dmesg | tail -50 for the underlying fault, run fsck on the filesystem from rescue/console, then remount.
  • Deletes became slower after enabling TRIM — online discard is the cause. Remove discard from /etc/fstab and rely on fstrim.timer instead.
  • Swap is configured but never used — swapon --show probably lists nothing, or the file has wrong permissions. Recheck with swapon --show and the swap file's 600 mode.
  • Write latency spiked after tuning — dirty limits set too low for the workload. Raise vm.dirty_ratio gradually and re-test with fio rather than changing several values at once.

Next steps

Was this guide helpful?

Still stuck?

Ask MdmHost AI for a quick answer, or open a ticket and our team will take a look. We are here 24/7.