In Linux, I/O schedulers fall into two categories: single-queue and
multi-queue.

Single-queue schedulers have a single queue, per device, of waiting I/O requests. Spinning drives are physically limited to servicing a single request at a time, so internally, they have only a single queue. For these devices on older machines, it made sense for I/O schedulers to also have only a single queue.

Advancing hardware brought higher counts of CPU cores, as well as single drives that could work on multiple requests in parallel. Multi-queue schedulers help with both aspects.

Having multiple CPU cores introduced more lock-contention working with the I/O queues. Creating a queue per core allowed most lock interaction to be delayed until sending requests to the drive, and eliminated most of the lock contention. If the drive also supports multiple queues, it allows less work to be done merging the kernel’s queues together before dispatching requests to the drives.

Modern kernels use multi-queue schedulers by default now, even for devices that have only a single hardware queue.

You can read about the different schedulers here: