Why this even matters
Every block device on Linux has an I/O scheduler sitting between your applications and the actual disk, deciding the order requests get sent in. Get the wrong one for your workload and you’re leaving real performance on the table, or worse, adding latency you didn’t need to.
Check what’s currently active and what else is available:
cat /sys/block/sda/queue/scheduler
The one in brackets is active. On modern kernels you’ll usually see some
combination of none, mq-deadline, kyber, and bfq listed.
none
Does exactly what it says … no reordering, no fairness logic, requests
go straight to the device in the order they arrive. Sounds dumb until you
realise that’s actually correct for very fast NVMe SSDs, which already
handle massive internal queue depths and parallelism in hardware. Any
scheduling logic on top just adds CPU overhead for no benefit. If you’re
on a genuinely fast NVMe drive, none is often the right call, not a
lack of configuration.
mq-deadline
The one I ended up on for my NAS. Deadline-based … every request gets a
deadline, and the scheduler makes sure nothing waits forever, while still
batching reads and writes efficiently for decent throughput on
traditional storage. Low overhead, predictable behaviour, and it doesn’t
try to be clever about latency-fairness the way bfq does.
For a file server pushing Samba/NFS traffic with a weak CPU behind it, that low overhead matters more than anything else. Set it with a udev rule so it survives reboots without having to remember to reapply it:
sudo tee /etc/udev/rules.d/60-ioscheduler.rules << 'EOF'
ACTION=="add|change", KERNEL=="sda", ATTR{queue/scheduler}="mq-deadline"
EOF
sudo udevadm control --reload-rules
sudo udevadm trigger --subsystem-match=block
kyber
Built by Google originally for their own datacenter SSDs. Tuned to hit specific target latencies on fast, multi-queue flash storage under genuinely mixed random I/O … think database or VM host workloads where you care about consistent response time under load, not raw sequential throughput.
I tried it briefly, expecting it to be a straightforward upgrade over
mq-deadline since it’s newer. It wasn’t, for my case specifically. My
drive isn’t fast or parallel enough to actually benefit from what
kyber is tuned for, and the scheduling logic itself costs more CPU than
mq-deadline does … on a weak APU with no crypto acceleration, that’s
not a trade worth making for a NAS that’s mostly doing large sequential
transfers, not latency-sensitive random access.
bfq
The default on a lot of desktop-oriented distros, including Fedora out of the box. Budget Fair Queuing … genuinely good at what it’s built for, which is keeping the system responsive when multiple things are competing for disk access at once, classic desktop scenario: you’re copying a big file while also launching an app and don’t want the whole system to stutter.
That fairness logic isn’t free though. It’s the heaviest of the four in terms of CPU overhead, doing real work to keep everything balanced. Fine on a desktop CPU with cycles to spare. Not fine on a box where the CPU is already the bottleneck and there’s no interactive desktop session to protect in the first place … a NAS doesn’t care about “responsiveness” the way a desktop does, it cares about throughput.
What I actually landed on, and why
mq-deadline, no contest, for this specific box:
SATA-attached storage, not NVMe, so
nonegives up too muchweak CPU, no AES-NI, already busy with Samba/NFS/SFTP/Tailscale … so
kyber’s andbfq’s extra scheduling overhead is a real cost, not a rounding errorNAS workload is throughput-oriented sequential transfers, not the latency-sensitive random I/O
kyberis actually built forno desktop session to protect, so
bfq’s fairness logic is solving a problem that doesn’t exist on this machine
If this were a fast NVMe drive: none. If it were a database or VM host
on fast flash: kyber. If it were a desktop I actually sit at: probably
bfq, the default’s the default for a reason there. None of these are
universally “the best” scheduler … they’re each solving a different
problem, and the only real mistake is picking one without knowing which
problem you actually have.