Filesystems · Flash and Block Layers
Wear Leveling and the Erase-Cycle Budget of a Flash Device
How erase counts are tracked, what dynamic and static leveling each accomplish, and why the endurance rating is a property of the worst block rather than the average.
A NAND cell tolerates a finite number of program/erase cycles before its threshold window narrows past what the error-correcting code can resolve. The number depends on the cell technology, the process node, and the error-correction strength the controller applies: SLC parts are commonly rated in the hundred-thousand-cycle range, MLC in the low thousands to low tens of thousands, TLC in the low thousands, and QLC in the hundreds. Those figures are per erase block, and they are a hard limit rather than a degradation curve to be traded against performance. A device fails when its worst block is exhausted, not when its average block is, so the entire problem is keeping the maximum erase count of any block as low as possible for a given amount of host traffic.
Why a naive mapping burns blocks
The mapping table described in the flash translation layer assigns logical addresses to physical pages without regard to how often each physical block is erased. If the host rewrites the same logical region repeatedly, and the allocator always takes free pages from the same pool, those blocks cycle while the rest of the device sits idle. A filesystem’s metadata region, its journal, and its superblock are rewritten constantly; a region holding an archive file is written once. The gap in erase counts between the two can be orders of magnitude, and the metadata blocks die while the capacity is barely used.
The fix is to decouple the physical block chosen for a write from the logical address being written. Every write takes a free page from wherever the allocator’s cursor is, and no logical address has a fixed physical home. That is already true of the page-level mapping scheme, which means wear leveling is partly a free consequence of remapping and partly a scheduling problem on top of it.
Dynamic leveling: use the free pool as the shuffle
Dynamic wear leveling confines itself to blocks in the free pool. When the allocator needs a free block, it picks the one with the lowest erase count rather than the next one in the pool. Since every host write eventually consumes a free block, and the free pool’s members have erase counts spanning some range, always choosing the minimum pulls the pool’s counts together and prevents any single free block from being repeatedly preferred.
Dynamic leveling alone cannot touch blocks holding data that is never rewritten. A block holding a file written once at the factory and never modified is never freed, so it never returns to the free pool, and its erase count stays at its initial value while the rest of the device climbs. The distribution of erase counts across the device widens as the device ages, and the maximum climbs faster than the mean. On a workload with a large static data set, dynamic leveling is not sufficient.
Static leveling: moving cold data to rest hot blocks
Static wear leveling moves valid data out of blocks whose erase count is low, so that those blocks become free and can absorb writes. The trigger is a threshold: when the gap between the highest and lowest erase count across all blocks exceeds some margin, the controller schedules a relocation of a low-count block’s valid pages. The block then re-enters the free pool with a low count and is selected for programming, raising its count and lowering the maximum’s relative advantage.
The cost of static leveling is copy traffic that the host did not request. Every relocated page is a program, and every relocated block adds an erase. On a device whose cold data is a large fraction of capacity, the steady-state rate of relocations is proportional to how fast the hot blocks are cycling and how wide the count gap is allowed to become. A narrow margin means frequent relocation and higher write amplification; a wide margin means less copying but a higher peak count and therefore a shorter life. The margin is a tunable that trades endurance against amplification, and drives do not expose it.
Some controllers maintain the count distribution explicitly: a table of erase counts per block, with blocks bucketed by count so the minimum and maximum are found without a scan. The table is small relative to the mapping table, one entry per erase block rather than per page, so a drive with a million blocks needs a few megabytes at most.
/* Static leveling: relocate cold blocks whose erase count lags the maximum. */
struct wear_state {
uint32_t max_erase_count;
uint32_t min_erase_count;
uint32_t gap_threshold;
};
static bool needs_static_leveling(const struct wear_state *w)
{
return (w->max_erase_count - w->min_erase_count) > w->gap_threshold;
}
/* Called with a block whose valid pages are all cold, chosen by the policy.
* The page-copy and erase helpers belong to the controller's mapping layer. */
static void relocate_cold_block(uint32_t block)
{
for (uint32_t p = 0; p < PAGES_PER_BLOCK; p++) {
if (!page_is_valid(block, p))
continue;
uint32_t dst = allocate_free_page(); /* lowest erase count first */
copy_page_and_update_map(block, p, dst); /* mapping table follows */
}
erase_and_release(block);
}
The subtlety is the choice of which cold block to relocate. Relocating the coldest block, the one with the lowest count, is the direct answer, but if that block’s contents will be rewritten next week, the relocation is wasted and the pages will be invalidated shortly after being copied. The same age signal used in victim selection for garbage collection applies here: relocate blocks whose data has been stable long enough to be worth the copy.
What the endurance rating actually measures
JEDEC’s endurance specifications define the test: a workload with a stated mix of sequential and random access, a stated data-retention requirement after the cycling, and a stated allowable error rate. A drive’s rating in terabytes written is the volume the device can absorb under that workload while meeting the retention and error requirements. Two drives with the same NAND and different over-provisioning or different leveling margins will have different ratings, and the rating is not the number of bytes that can be written before the first block fails; it is the number that can be written while the device still meets its specification.
The distinction matters because it explains why a drive that is heavily over-provisioned can be rated for several times the writes of one that is not. Over-provisioning reduces the valid fraction of blocks being reclaimed, which lowers write amplification, which means fewer erases per host byte. Endurance in host bytes is therefore the product of the raw cycle budget and the reciprocal of amplification. Wear leveling affects the numerator only insofar as it prevents any block from reaching the budget early; the denominator is the garbage collection efficiency.
Retention interacts with both. A block that has been cycled many times holds charge less reliably, and the retention requirement in the JEDEC specification is measured after cycling. A device can pass its cycle count and fail retention, or vice versa, so the endurance figure is a joint statement about cycling and time at temperature. The temperature dependence is steep: retention at elevated temperature degrades much faster than at room temperature, which is why the specification states the retention condition explicitly rather than leaving it implicit.
Read disturb and the counter that is not erase cycles
A block can degrade without being erased. Every read of a page applies a pass voltage to the other wordlines in the block, and the cumulative effect shifts the thresholds of cells that were not being read. After enough reads, the block returns errors on pages that were written once and never touched. Controllers track a read count per block and relocate a block whose count exceeds a threshold, which is a form of wear management that has nothing to do with erase cycles.
The read-disturb threshold depends on the cell technology and the error-correction margin, and it moves in the wrong direction as bits per cell increase: a narrower threshold window leaves less room for the shift that reads cause, so a TLC or QLC block tolerates fewer reads before relocation than an SLC block of the same generation. Published figures range from tens of thousands to millions of reads per block depending on the part. The practical consequence is that a read-only workload still generates writes at a rate proportional to how often it rereads the same block. A backup that is verified by reading it repeatedly can consume the device’s endurance without writing a byte of user data.
Reporting and the limits of host visibility
A host can read the device’s SMART attributes, which include a percentage of rated endurance used, a count of blocks that have been retired, and an average or worst-case erase count depending on the drive’s reporting. Those counters are the only view the host gets, and they are coarse: the drive reports a percentage, not a distribution, and the mapping from raw counts to the percentage is vendor-specific.
Nothing in the block layer lets a host influence wear leveling directly. The two levers that exist are indirect. Free-space signalling through discard lets the controller reclaim blocks without copying, which lowers amplification and therefore the erase rate. Keeping the device below full capacity leaves the collector room to choose empty victims, which does the same. Both are covered in the discard mechanism, and both matter more to the device’s life than any host-side attempt to order writes by expected lifetime, because the controller’s mapping is what decides where a write lands.
References
- JESD218: Solid-State Drive (SSD) Requirements and Endurance Test Method — JEDEC Solid State Technology Association
- JESD219A: Solid State Drive (SSD) Endurance Workloads — JEDEC Solid State Technology Association
- Inside NAND Flash Memories — Micheloni, Crippa, Marelli, Springer