Linux Kyber I/O Scheduler for Fast Block Devices
This article provides an overview of the Kyber I/O scheduler in the Linux operating system, detailing its architecture, purpose, and operational mechanics. Designed specifically for modern multi-queue block devices such as high-performance NVMe solid-state drives, Kyber balances low latency with high throughput by dynamically managing request queues. Readers will learn how Kyber prevents I/O starvation, regulates queue depths based on configurable latency targets, and compares to other Linux schedulers.
The Purpose of the Kyber Scheduler
Traditional Linux I/O schedulers like CFQ (Completely Fair Queuing)
and BFQ (Budget Fair Queuing) were designed for spinning disks where
minimizing head movement was paramount. As solid-state drives (SSDs) and
Non-Volatile Memory Express (NVMe) devices emerged, the overhead of
complex scheduling algorithms became a CPU bottleneck. Conversely, using
no scheduler at all (none) allows fast hardware to maximize
throughput but risks high tail latency under heavy workloads.
Introduced in Linux kernel 4.12, Kyber addresses this challenge. It
is a lightweight scheduler designed for the Linux multi-queue block
layer (blk-mq), offering fine-grained latency guarantees
with minimal CPU overhead.
Core Architecture and Mechanisms
Kyber operates on a simple principle: prioritize latency-sensitive requests while maintaining maximum hardware saturation. It achieves this by dividing incoming I/O operations into distinct categories, primarily synchronous reads and writes, and managing them through two primary mechanisms:
- Target Latencies: Kyber relies on pre-configured latency targets. By default, it aims for read requests to complete within 2 milliseconds and synchronous write requests to complete within 10 milliseconds.
- Dynamic Queue Depth Throttling: Kyber continuously measures the time it takes for the hardware to complete dispatched requests. If the completion latency remains below the configured target, Kyber increases the number of requests it sends simultaneously to the device. If the completion latency exceeds the target, Kyber throttles the dispatch queue depth, holding lower-priority requests in software queues until device latency drops.
Role in Preventing Starvation
On modern fast storage, long queues can lead to bufferbloat inside the storage controller. When heavy background writes saturate an NVMe drive, latency-sensitive read operations can experience significant delays.
Kyber's role is to prevent this degradation. By limiting the number of in-flight requests granted to the device controller at any single moment, Kyber ensures that urgent read requests are not trapped behind large bursts of bulk write operations. Because Kyber manages queues in software rather than letting requests pile up in hardware buffers, high-priority transactions can be scheduled ahead of lower-priority background tasks.
Minimal CPU Overhead
Unlike complex schedulers that track per-process bandwidth allocations, Kyber maintains very little internal state. It uses simple token-bucket-style dispatching and fast statistical sampling of completion times. This low-complexity design ensures that the scheduler does not consume excessive CPU cycles when handling millions of Input/Output Operations Per Second (IOPS).
Typical Use Cases
Kyber is best suited for:
- High-performance NVMe SSDs: Environments where storage hardware can handle massive parallel operations without needing traditional mechanical sorting.
- Latency-sensitive workloads: Web servers, real-time caches, and transactional databases where tail latency spikes (99th percentile) must be minimized.
- Mixed read/write environments: Systems where continuous write activity threatens to degrade read performance.
By dynamically governing queue depths to meet latency thresholds, the Kyber scheduler enables Linux to deliver predictable response times from modern flash storage without sacrificing device throughput.