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:

  1. 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.
  2. 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:

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.