Docs / Linux Basics / Linux Disk Scheduling Algorithms Explained

Linux Disk Scheduling Algorithms Explained

By Admin · Mar 15, 2026 · Updated Apr 23, 2026 · 150 views · 2 min read

Disk I/O scheduling determines the order in which read and write requests are serviced. Choosing the right scheduler for your workload can significantly improve performance, especially under heavy I/O load.

Available Schedulers

# Check available schedulers for a disk
cat /sys/block/vda/queue/scheduler
# [none] mq-deadline kyber bfq

# The current scheduler is shown in brackets

none (No-op)

Passes I/O requests directly to the disk with no reordering. Best for NVMe SSDs and virtualized environments where the hypervisor handles scheduling.

mq-deadline

Ensures every I/O request is serviced within a deadline. Prevents starvation where large sequential writes starve small random reads.

bfq (Budget Fair Queueing)

Provides fair I/O bandwidth distribution among processes. Excellent for multi-tenant servers where fair sharing matters.

kyber

A lightweight scheduler designed for fast NVMe devices. Uses token-based throttling to maintain low latency.

Choosing the Right Scheduler

# Recommendations by storage type:
# NVMe SSD:    none or kyber (minimal overhead)
# SATA SSD:    mq-deadline or kyber
# HDD:         mq-deadline or bfq
# Virtual disk: none (host handles scheduling)

Changing the Scheduler

# Change temporarily
echo "mq-deadline" | sudo tee /sys/block/vda/queue/scheduler

# Change permanently with udev rule
cat << EOF | sudo tee /etc/udev/rules.d/60-scheduler.rules
ACTION=="add|change", KERNEL=="nvme[0-9]*", ATTR{queue/scheduler}="none"
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="mq-deadline"
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="1", ATTR{queue/scheduler}="bfq"
EOF
sudo udevadm control --reload-rules

Benchmarking I/O Performance

# Install fio (Flexible I/O Tester)
sudo apt install fio

# Random read test (simulates database workload)
fio --name=randread --ioengine=libaio --direct=1 
    --bs=4k --numjobs=4 --size=1G --runtime=30 
    --rw=randread --group_reporting

# Random write test
fio --name=randwrite --ioengine=libaio --direct=1 
    --bs=4k --numjobs=4 --size=1G --runtime=30 
    --rw=randwrite --group_reporting

# Mixed read/write (70/30 split, typical web server)
fio --name=mixed --ioengine=libaio --direct=1 
    --bs=4k --numjobs=4 --size=1G --runtime=30 
    --rw=randrw --rwmixread=70 --group_reporting

Monitoring I/O Performance

# Real-time I/O statistics
iostat -x 2

# Key columns:
# r/s, w/s:     Reads/writes per second
# await:        Average latency per request (ms)
# %util:        How busy the disk is

# Per-process I/O
sudo iotop -o

For most Kazepute Breezes running on NVMe storage with KVM virtualization, the none scheduler provides the best performance since the hypervisor handles I/O scheduling at the host level.

Was this article helpful?