Storage media: what each one is made of and what it forces
One dial: stability versus mutability
To store one bit you need a physical object with two stable states (0 and 1) and a hill between them. Imagine a ball resting in one of two valleys, with a ridge between the valleys.
- A tall ridge: the ball stays where it is for years (good: data survives). But pushing it over to the other valley takes a lot of effort (bad: writing is slow and costs energy).
- A short ridge: writing is easy and cheap. But heat is constant microscopic shaking, and sooner or later it knocks the ball over by itself (bad: data leaks away).
You cannot have a tall ridge for storing and a short ridge for writing. It is the same ridge.
The equation
The Arrhenius relation says that retention time grows like
- the height of the ridge
- temperature
- a physical constant
Data table
| Barrier height E_b / kT | Retention (× the design at 40) |
|---|---|
| 30 | 0× |
| 30.4 | 0× |
| 30.8 | 0× |
| 31.1 | 0× |
| 31.5 | 0× |
| 31.9 | 0× |
| 32.3 | 0× |
| 32.6 | 0.001× |
| 33 | 0.001× |
| 33.4 | 0.001× |
| 33.8 | 0.002× |
| 34.1 | 0.003× |
| 34.5 | 0.004× |
| 34.9 | 0.006× |
| 35.3 | 0.009× |
| 35.6 | 0.013× |
| 36 | 0.018× |
| 36.4 | 0.027× |
| 36.8 | 0.039× |
| 37.1 | 0.056× |
| 37.5 | 0.082× |
| 37.9 | 0.119× |
| 38.3 | 0.174× |
| 38.6 | 0.253× |
| 39 | 0.368× |
| 39.4 | 0.535× |
| 39.8 | 0.779× |
| 40.1 | 1.13× |
| 40.5 | 1.65× |
| 40.9 | 2.4× |
| 41.3 | 3.49× |
| 41.6 | 5.08× |
| 42 | 7.39× |
| 42.4 | 10.8× |
| 42.8 | 15.6× |
| 43.1 | 22.8× |
| 43.5 | 33.1× |
| 43.9 | 48.2× |
| 44.3 | 70.1× |
| 44.6 | 102× |
| 45 | 148× |
| 45.4 | 216× |
| 45.8 | 314× |
| 46.1 | 457× |
| 46.5 | 665× |
| 46.9 | 968× |
| 47.3 | 1,410× |
| 47.6 | 2,050× |
| 48 | 2,980× |
| 48.4 | 4,340× |
| 48.8 | 6,310× |
| 49.1 | 9,180× |
| 49.5 | 13,400× |
| 49.9 | 19,400× |
| 50.3 | 28,300× |
| 50.6 | 41,200× |
| 51 | 59,900× |
| 51.4 | 87,100× |
| 51.8 | 127,000× |
| 52.1 | 184,000× |
| 52.5 | 268,000× |
| 52.9 | 390,000× |
| 53.3 | 568,000× |
| 53.6 | 827,000× |
| 54 | 1,200,000× |
| 54.4 | 1,750,000× |
| 54.8 | 2,550,000× |
| 55.1 | 3,700,000× |
| 55.5 | 5,390,000× |
| 55.9 | 7,840,000× |
| 56.3 | 11,400,000× |
| 56.6 | 16,600,000× |
| 57 | 24,200,000× |
| 57.4 | 35,100,000× |
| 57.8 | 51,100,000× |
| 58.1 | 74,400,000× |
| 58.5 | 108,000,000× |
| 58.9 | 158,000,000× |
| 59.3 | 229,000,000× |
| 59.6 | 333,000,000× |
| 60 | 485,000,000× |
where E_b is the height of the ridge, T is temperature, and k is a physical constant. The important point is that the ridge height is inside an exponent, so a small increase gives a huge change.
So retention, write speed, write energy and endurance (how many times you can rewrite before the cell wears out) are not four separate properties. They are one dial. Being non-volatile means resisting change. Being fast to write means being easy to change. You ask one material to be stubborn and flexible at the same time.
The ladder
| Memory | What it is | Retention | Write speed | Endurance |
|---|---|---|---|---|
| SRAM | Transistors held in state by power (CPU caches) | only while powered | ~ns | unlimited |
| DRAM | A tiny capacitor (a charge bucket) per bit — your RAM | ~64 ms, so it is refreshed constantly | ~10 ns | unlimited |
| NAND flash | Charge trapped behind an insulating layer (SSDs, USB sticks) | years | ~500 µs, high voltage | 1,000–100,000 rewrites |
| Tape | Magnetic regions on a plastic ribbon, no power | ~30 years | slow, sequential only | high |
Wear is not a manufacturing defect. NAND flash wears out because it keeps data for a decade. The insulating layer that traps the charge must be tunneled through by electrons to write, and each tunneling creates tiny defects in the layer. After many writes the layer leaks. The retention is the cause of the wear.
Why there is no "universal memory". For thirty years researchers have tried to build one memory that is fast, dense, durable and cheap (FeRAM, MRAM, PCM, Intel Optane, racetrack). Each was good at three of the four, never all four. They are not failing to try. They are asked to set one dial to two positions.
Cheap means coarse
A storage device has two parts: the mechanism (the machinery that reads and writes: a disk arm, an erase circuit, a tape head, a network round trip) and the medium (the bits themselves). The mechanism is expensive; the medium is cheap.
To get a low price per bit, you must spread the mechanism's cost over as many bits as possible. This is called amortization. But bits that share one mechanism must be operated on together — that is what "sharing" means. And "operated on together" is the definition of coarse granularity.
- One tape head serves kilometers of ribbon: cheapest per TB, but reading means winding the spool.
- One disk arm serves 20 TB: cheap, but random access means physically moving the arm.
- One flash erase circuit serves a block of 4–24 MB: cheap, but you cannot erase less than a block.
- One HTTP request serves one object in cloud storage: cheap, but you cannot change less than a whole object.
The price ladder and the granularity ladder are the same ladder. You get cheapness by accepting coarseness.
So when you later read about write amplification in flash, zone rewrites in SMR disks, and the small-files problem in object storage, remember: they are not four problems. They are one problem at four price points.
Fixed cost and the natural transfer size
Every mechanism has a setup cost that is paid for each operation, whatever its size: moving a disk arm, erasing a flash block, a TLS handshake (the secure-connection setup on the web) and metadata lookup in an object store, repositioning a tape. So
- the setup cost paid for each operation, whatever its size
- bytes per second once data streams
- bytes moved per operation
- the size at which half of your time is setup
Data table
| Request size x | series | Time spent transferring |
|---|---|---|
| 1,000 B | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 0.025% |
| 1.16 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 0.03% |
| 1.38 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 0.035% |
| 1.64 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 0.042% |
| 1.95 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 0.05% |
| 2.32 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 0.059% |
| 2.75 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 0.07% |
| 3.27 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 0.084% |
| 3.89 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 0.099% |
| 4.62 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 0.118% |
| 5.49 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 0.14% |
| 6.53 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 0.167% |
| 7.76 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 0.198% |
| 9.22 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 0.235% |
| 11 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 0.28% |
| 13 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 0.332% |
| 15.5 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 0.395% |
| 18.4 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 0.469% |
| 21.9 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 0.557% |
| 26 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 0.661% |
| 30.9 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 0.784% |
| 36.7 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 0.931% |
| 43.6 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 1.1% |
| 51.8 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 1.31% |
| 61.6 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 1.55% |
| 73.2 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 1.84% |
| 87 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 2.18% |
| 103 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 2.58% |
| 123 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 3.05% |
| 146 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 3.61% |
| 174 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 4.26% |
| 206 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 5.02% |
| 245 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 5.91% |
| 292 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 6.95% |
| 346 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 8.15% |
| 412 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 9.54% |
| 489 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 11.1% |
| 582 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 13% |
| 691 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 15% |
| 822 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 17.4% |
| 977 KB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 20% |
| 1.13 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 22.9% |
| 1.35 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 26.1% |
| 1.6 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 29.6% |
| 1.9 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 33.3% |
| 2.26 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 37.2% |
| 2.69 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 41.3% |
| 3.19 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 45.6% |
| 3.8 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 49.9% |
| 4.51 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 54.2% |
| 5.36 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 58.4% |
| 6.37 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 62.6% |
| 7.58 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 66.5% |
| 9 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 70.2% |
| 10.7 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 73.7% |
| 12.7 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 76.9% |
| 15.1 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 79.8% |
| 18 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 82.5% |
| 21.4 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 84.8% |
| 25.4 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 86.9% |
| 30.2 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 88.8% |
| 35.8 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 90.4% |
| 42.6 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 91.8% |
| 50.6 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 93% |
| 60.2 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 94% |
| 71.5 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 94.9% |
| 85 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 95.7% |
| 101 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 96.4% |
| 120 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 96.9% |
| 143 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 97.4% |
| 170 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 97.8% |
| 202 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 98.1% |
| 240 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 98.4% |
| 285 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 98.7% |
| 338 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 98.9% |
| 402 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 99.1% |
| 478 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 99.2% |
| 568 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 99.3% |
| 675 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 99.4% |
| 802 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 99.5% |
| 954 MB | object storage (F ≈ 50 ms, B ≈ 80 MB/s) | 99.6% |
| 1,000 B | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 0.077% |
| 1.16 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 0.091% |
| 1.38 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 0.109% |
| 1.64 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 0.129% |
| 1.95 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 0.153% |
| 2.32 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 0.182% |
| 2.75 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 0.216% |
| 3.27 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 0.257% |
| 3.89 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 0.305% |
| 4.62 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 0.363% |
| 5.49 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 0.431% |
| 6.53 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 0.511% |
| 7.76 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 0.607% |
| 9.22 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 0.721% |
| 11 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 0.856% |
| 13 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 1.02% |
| 15.5 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 1.2% |
| 18.4 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 1.43% |
| 21.9 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 1.69% |
| 26 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 2.01% |
| 30.9 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 2.37% |
| 36.7 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 2.81% |
| 43.6 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 3.32% |
| 51.8 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 3.92% |
| 61.6 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 4.63% |
| 73.2 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 5.45% |
| 87 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 6.42% |
| 103 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 7.53% |
| 123 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 8.83% |
| 146 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 10.3% |
| 174 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 12% |
| 206 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 14% |
| 245 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 16.2% |
| 292 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 18.7% |
| 346 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 21.4% |
| 412 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 24.5% |
| 489 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 27.8% |
| 582 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 31.4% |
| 691 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 35.3% |
| 822 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 39.3% |
| 977 KB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 43.5% |
| 1.13 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 47.8% |
| 1.35 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 52.1% |
| 1.6 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 56.4% |
| 1.9 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 60.5% |
| 2.26 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 64.6% |
| 2.69 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 68.4% |
| 3.19 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 72% |
| 3.8 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 75.4% |
| 4.51 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 78.4% |
| 5.36 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 81.2% |
| 6.37 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 83.7% |
| 7.58 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 85.9% |
| 9 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 87.9% |
| 10.7 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 89.6% |
| 12.7 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 91.1% |
| 15.1 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 92.4% |
| 18 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 93.5% |
| 21.4 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 94.5% |
| 25.4 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 95.3% |
| 30.2 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 96.1% |
| 35.8 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 96.7% |
| 42.6 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 97.2% |
| 50.6 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 97.6% |
| 60.2 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 98% |
| 71.5 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 98.3% |
| 85 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 98.6% |
| 101 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 98.8% |
| 120 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 99% |
| 143 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 99.1% |
| 170 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 99.3% |
| 202 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 99.4% |
| 240 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 99.5% |
| 285 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 99.6% |
| 338 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 99.6% |
| 402 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 99.7% |
| 478 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 99.7% |
| 568 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 99.8% |
| 675 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 99.8% |
| 802 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 99.8% |
| 954 MB | hard disk (F ≈ 13 ms, B ≈ 100 MB/s) | 99.9% |
Batching
When the fixed cost is large, the sensible move is to batch: pay the setup once and spread it over more bytes. Think of an elevator: it is wasteful to go up with one parcel, so you wait until you have a full trolley. But batching means the first item waits for the last item. This is the latency versus throughput trade-off. It is not a separate law; it is a consequence of non-zero fixed cost. If setup were free, batching would give nothing.
The natural transfer size
Every medium has a natural transfer size. Multiply the fixed cost by the transfer rate and you find the size at which half of your time is setup. Below it you mostly pay for setup.
Four questions for every storage medium
- What are its smallest units of read, of write, and of reclaim (freeing space)? A mismatch between them creates amplification.
- What is the fixed cost per operation? This gives the natural batch size.
- How much concurrency is needed to reach full throughput? This shows where the tail-latency knee is.
- Can it update in place? If not, there is an indirection layer and a garbage collector. Go and find them.
The rest of this page is one medium after another answering these four questions.