Storage Latency Arrives in Microseconds and Gets Graphed in Milliseconds
Every figure a storage engineer collects about a drive lands in microseconds. A load generator reports completion latency in µs, an NVMe datasheet promises a 4K random read in the tens of µs, the device telemetry counts in µs — and then the alert rule someone wrote years ago fires on a millisecond threshold, and the dashboard panel is drawn with a millisecond axis. Nothing in that chain is wrong; the units simply refuse to agree, and the first job when a latency graph looks odd is getting all of it onto one scale.
Why the Two Scales Keep Colliding
Datasheets and dashboards sit three zeros apart
The tail is the part people feel
Queueing time rides on top of service time
IOPS and latency are one measurement twice
Putting a Benchmark Result Beside an Alert Threshold
The usual sequence starts with a raw µs figure out of a load generator and ends with a threshold you can defend in a design review.
Enter the percentile you actually care about
Type the p99 or p99.9 completion latency from the run — 250, 850, 12,400. The millisecond value appears while you type. Spaces used as thousands separators are ignored, and a comma decimal separator works as well as a dot.
Line it up against the panel's units
Read the result beside whatever the graph is drawn in. A p99 that converts to 0.85 ms will barely lift a line scaled to 20 ms, which is exactly how a genuine regression stays hidden in plain sight for a quarter.
Work backwards from a millisecond SLO
The swap control (↔) reverses the pair to ms → µs, the direction you need when a service owner hands you a 5 ms budget and it has to be split into a media allowance and a fabric allowance in microseconds.
Paste the plain number into the rule
The copy control hands over digits only — no unit, no separators — so the value drops straight into an alert expression or a capacity sheet with nothing to tidy up afterwards.
Access Latency Across the Storage Stack
Typical service times for a small random read at low queue depth, with the same value written both ways. Treat each row as the order of magnitude that medium lives at rather than a promise about a particular part number.
| Medium or path | What is being timed | Service time (µs) | Same value (ms) |
|---|---|---|---|
| DRAM read | Included only as the floor of the stack | 0.1 µs | 0.0001 ms |
| Storage-class memory NVMe | 4K random read, queue depth 1 | 10 µs | 0.01 ms |
| NAND NVMe SSD | 4K random read, queue depth 1 | 25 µs | 0.025 ms |
| SATA SSD | 4K random read, protocol overhead included | 120 µs | 0.12 ms |
| SAN fabric round trip | Added to every I/O, media time excluded | 150 µs | 0.15 ms |
| 15k SAS drive | 3.4 ms average seek plus 2 ms rotational | 5,400 µs | 5.4 ms |
| 7.2k SATA drive | 8.5 ms average seek plus 4.17 ms rotational | 12,700 µs | 12.7 ms |
Five orders of magnitude separate the top row from the bottom one, and the interesting boundary sits in the middle. Everything on flash is a fraction of a millisecond, so a millisecond graph draws the whole array as a flat line near zero until something breaks. Everything with a platter is measured in whole milliseconds, where microseconds have stopped mattering at all — the rotational component alone, fixed by the spindle speed, dwarfs any protocol saving.
What Helps When the Numbers Are This Small
One field drives the other
Both boxes accept input, so a whole percentile ladder — p50, p95, p99, p99.9 — can be walked through in one pass with nothing to reset between entries.
Flip it when the budget is stated in ms
Swapping to ms → µs is how a service-level target gets broken into the per-layer allowances a storage design has to hit.
Nanoseconds and hours share the dropdown
Searchable unit lists on both sides cover the full time range, so a cache hit quoted in ns and a rebuild window quoted in hours both belong on this page.
Tiny results keep their digits
Output carries up to eight decimals and moves to scientific notation below a millionth, so a sub-microsecond value never collapses to a bare zero on screen.
Questions From the Storage Bench
What does a p99 of 900 µs tell me that the average does not?
It describes the worst one per cent, which is the part that produces complaints. A run can report a 90 µs mean and a 900 µs p99 at once: ninety-nine requests finished quickly and the hundredth waited ten times longer behind a garbage-collection pause, a lock, or a full queue. The mean is dominated by the common case, the percentile by the rare one — and a request that touches many objects keeps running into the rare one.
Why do NVMe datasheets quote microseconds when my dashboard plots milliseconds?
They were built for different eras of hardware. A 25 µs read written as 0.025 ms loses all its resolution on an axis scaled for spinning disks, and a panel inherited from a 7.2k SATA array draws the entire flash tier as a flat line hugging zero. Rescaling the panel, or at least converting before you compare, is what makes a doubling from 25 µs to 50 µs visible instead of invisible.
Does raising queue depth make each individual I/O slower?
Once the device is saturated, yes. The media still answers in the same time, but every request now waits behind those already outstanding, and that waiting is counted in the completion latency your tools print. A drive answering in 80 µs at queue depth 1 can report 600 µs at queue depth 64 while delivering far more IOPS. Sweep the depth in small steps and note the knee where latency climbs faster than throughput; that point, not the peak IOPS number, is the honest operating limit.
How do I get an IOPS figure out of a service time in microseconds?
Divide the number of outstanding requests by the latency expressed in seconds. One request in flight at 100 µs is 1 ÷ 0.0001 = 10,000 IOPS, and a 25 µs drive gives 40,000 on the same basis. Concurrency multiplies it: thirty-two outstanding requests at 250 µs each comes to 128,000 IOPS. This is also why a single-threaded test of a fast drive produces a disappointing throughput number — the drive was never the constraint, the concurrency was.
Would anyone ever notice 200 µs between two drives?
Never on its own; 0.2 ms is far below anything a person can perceive. It becomes visible through multiplication. A query plan that walks two hundred index pages turns that gap into 40 ms of extra wall-clock time, and an endpoint that fans out across several such queries multiplies it again. Judge latency at this scale only after the amplification factor of the access pattern, never per I/O.
No comments yet. Be the first to comment!