A storage datasheet promises a number. "Up to 1,000,000 IOPS." You size your workload against it, buy the array, put it into production, and watch it struggle at a fraction of the figure. The datasheet didn't lie, exactly. It just measured a storage system under laboratory conditions that have nothing to do with your Tuesday afternoon.
IOPS — input/output operations per second — is the most quoted and least useful single number in storage. Not because it's meaningless, but because a bare IOPS figure without its conditions is like a car's top speed measured downhill with a tailwind. Technically achieved. Irrelevant to your commute.
The four variables the headline number hides
An IOPS figure only means something alongside the conditions that produced it. Four variables move the number enormously:
Block size. The headline figure is almost always measured at 4 KB blocks, because small blocks maximize the operation count. Your database might do 8 KB or 16 KB. Your backup job does megabyte-sized sequential chunks. The same array that hits a million 4 KB IOPS might do a tenth of that operation count at 64 KB — though it's moving far more data per operation. IOPS and throughput (MB/s) are different measurements, and optimizing the one the datasheet quotes can mean nothing for the one your workload needs.
Read/write mix. Datasheets love 100% read numbers because reads are cheaper than writes, especially on flash, where writes carry erase-cycle and garbage-collection overhead. Your real workload is some mix — maybe 70/30, maybe 50/50. A 100%-read headline can be double or more what a realistic mixed workload delivers.
Queue depth. This is the big one, and the most quietly misleading. Reaching peak IOPS requires keeping the storage deeply fed — dozens or hundreds of operations in flight at once (high queue depth). That's how benchmarks are run: synthetic tools blasting the array with maximum concurrency. Many real workloads, especially latency-sensitive ones, run at low queue depth — a few operations in flight, each waiting on the last. At queue depth 1, you're measuring latency, not throughput, and the IOPS number collapses to a tiny fraction of the headline.
Sustained vs. burst. Flash arrays can absorb a burst of writes into cache and fast tiers at spectacular rates, then slow dramatically once the cache fills and garbage collection kicks in. The datasheet burst number is real for the first few seconds and a fantasy for a sustained production load. Spinning disk doesn't have this cliff as sharply, but has its own — sequential vs. random performance differ by an order of magnitude.
What your workload actually asks for
The number that matters is not the array's peak. It's the match between what your workload demands and what the array delivers under your workload's conditions.
- A transactional database does lots of small, random, latency-sensitive reads and writes at modest queue depth. It cares about latency at realistic concurrency far more than peak IOPS at queue depth 256.
- A virtualization host blends many VMs into a nearly random aggregate — the "IO blender" — so it cares about random mixed performance, not sequential peaks.
- A backup target or media server does large sequential transfers and cares about sustained throughput (MB/s), where IOPS is almost the wrong metric entirely.
- A VDI deployment has brutal correlated bursts (boot storms, login storms) that punish anything optimized only for steady-state.
Size against the workload's real profile, not the datasheet's best case.
How to not get trapped
Know your workload's IO signature before you shop. Pull real numbers from the existing system: average and peak IOPS, block sizes, read/write ratio, and the queue depths you actually run at. Most storage and OS tools expose all of this. Shopping without it is guessing.
Read the fine print on every benchmark. A quoted IOPS figure without block size, read/write mix, and queue depth is marketing, not specification. Make the vendor state the conditions, then judge whether those conditions resemble your load.
Weigh latency as heavily as IOPS. For most interactive workloads, consistent low latency at realistic concurrency matters more than a peak throughput you'll never sustain. An array that delivers 50,000 IOPS at sub-millisecond latency under your real mix beats one that benchmarks at 500,000 and spikes to 20 ms under load.
Test with your data, not theirs. If the purchase is large enough, run a proof of concept with a replay of your actual IO, or at least a synthetic profile that matches your measured signature. The gap between datasheet and reality is exactly where a storage plan goes to die.
The headline IOPS number isn't a lie. It's an answer to a question you're not asking. The operator's job is to ask the right question — how does this array perform under my block size, my read/write mix, my queue depth, sustained — and insist on an answer measured the same way.