A hard disk is the last great mechanical device in your computer: a stack of platters spinning at
5 400–15 000 RPM under a head that must physically fly to the right track before it can read a
byte. That machinery makes the disk the one place in the system where the order you issue
requests changes how long they take — sometimes by an order of magnitude. The
This lesson does two things. First, the mechanics: exactly what makes a random read cost ~10 ms while a sequential read of the same data costs almost nothing. Second, the classic disk-scheduling algorithms — FCFS, SSTF, the SCAN "elevator" family, deadline, CFQ/BFQ — and the twist that makes half of them obsolete on an SSD, where there is no head to move at all.
The time to service a single random request is a sum of three physically distinct parts:
Add them up: a random 4 KiB read is roughly
Because seek time grows with how far the head moves, and because many requests sit in the queue at once,
the OS can reorder them to shrink total head travel. This is the classic disk-scheduling problem.
Suppose the head is at cylinder 53 and the queue holds requests for
| Algorithm | Idea | Strength | Weakness |
|---|---|---|---|
| FCFS | serve in arrival order | fair, simple, no starvation | wild head swings — worst travel |
| SSTF | always nearest request next | low average seek | starves far-away requests |
| SCAN (elevator) | sweep one way, then reverse | bounded wait, good travel | edges wait longest |
| C-SCAN | sweep one way, snap back, repeat | uniform wait times | the return trip is "wasted" |
| Deadline | elevator + expiry deadlines | bounds worst-case latency | slightly lower throughput |
| CFQ / BFQ | fair-share time slices per process | interactive fairness | overhead; less raw throughput |
The elevator metaphor is the key intuition: a lift does not rush to whoever pressed the button most recently (that would ping-pong forever). It sweeps steadily up serving every request in its path, then sweeps down. SCAN does exactly this with the disk head — bounding how long any request can wait while still keeping the arm moving efficiently. Deadline refines it by attaching an expiry to each request (e.g. reads 500 ms, writes 5 s); an expiring request jumps the queue, guaranteeing no request starves — the default choice on Linux for spinning disks.
The simulation runs the same request queue through FCFS (arrival order) and SCAN (the elevator, sweeping toward larger cylinders first), and totals the head movement. The elevator's win is the reduction in total cylinders travelled — directly proportional to total seek time.
Every scheduler above optimises for one physical fact: moving the head is slow and distance
matters. An SSD has no head. Any logical block is reachable in about the same ~100 µs no
matter where the last one was — access time is essentially uniform and random-friendly. So the
elaborate elevator logic buys nothing and its sorting overhead actually hurts. That is why Linux
pairs SSDs with none (the old "noop") or the lightweight mq-deadline/kyber
schedulers: skip the reordering, just merge adjacent requests and fire them at the device's many parallel
queues as fast as possible. The scheduler you pick is a statement about the physics of the media
underneath — and NVMe's blk-mq multi-queue design leans into that parallelism rather than fighting it.
Students often blur "shortest seek" (SSTF) with "the elevator" (SCAN) because both prefer nearby requests. They are different, and the difference is starvation. SSTF always jumps to the globally nearest pending request. If a steady trickle of requests keeps arriving near the head, a lone request out at cylinder 190 can wait forever — it is never the nearest. SCAN cannot do this: it commits to a direction and sweeps, so every request is guaranteed service within one full pass, no matter how many closer ones arrive. Low average seek is not enough; a real scheduler must also bound the worst case. That is the whole reason deadline schedulers exist.
Put numbers on a single access. A 7 200 RPM disk has average seek 9 ms and transfers at 150 MB/s. What is the expected time to read one random 4 KiB block?
none/mq-deadline —
reordering by distance is pointless without a head.