§ 01Five kinds of non-volatile memory that behave nothing alike

Not all memory is created equal — and in embedded work, confusing the types costs time, sometimes money, and occasionally a part. Non-volatile memory holds its contents without power; that much is shared. Everything else diverges: how you write it, how fast it reads, how many times it tolerates a write cycle, and whether the bus connects inside the die or through external pins.[1]

Table 1 — five non-volatile memory types, told apart
TypeHow it’s writtenSmallest eraseWearWhat it’s for
Mask ROMAt manufacture, in the maskNot erasableNoneCode that will never change, at volume.
EEPROMByte at a time, in circuitOne byte~100k–1M cyclesSmall settings that change often.
NOR flashWord at a timeA whole sector~10k–100k cyclesProgram code you execute in place.
NAND flashA page at a timeA whole block~1k–100k cyclesBulk storage, with a controller managing wear.
FRAMByte at a time, fastNot required~10^12+ cyclesLogging, and anything written constantly.

§ 02The Five, One at a Time

ROM. Mask ROM is programmed at the factory by the lithography itself — the data is baked into the metal layers during fabrication. You cannot change it. It appears in high-volume consumer chips where the firmware is final before tape-out, because the economics flip when you're shipping tens of millions of identical units. At the workbench it is invisible: you don't buy mask-ROM parts and write to them. What you do encounter is its conceptual descendants.

a bare printed circuit board in raking light, macro Enlarge ⤢
Fig. 2 — Non-volatile memory, sitting where you will have to erase it.

OTP. The closest of those descendants, One-Time Programmable memory, is electrically writable, but only once. Internally it is usually an array of fusible links or antifuse cells; applying a programming voltage either blows the link or forms it, permanently. Some microcontrollers include a small OTP region alongside their main flash, used for a device serial number or a calibration trim value the factory programs once and freezes. The "one-time" is absolute — there is no erase.

EEPROM. Electrically Erasable Programmable Read-Only Memory can be written and erased byte by byte, in place, with no bulk erase step required. That random-access write ability is its defining feature. The cost is endurance: a typical cell survives somewhere in the range of a hundred thousand write cycles before the oxide degrades enough to cause errors. EEPROMs appear as standalone serial devices on an I²C or SPI bus — small packages storing a few kilobytes of configuration data, calibration constants, or a log that updates every few seconds. Many microcontrollers also include a small internal EEPROM block for exactly that kind of wear-limited, byte-granular storage. Write latency is measured in milliseconds per byte, not microseconds, so you never execute code from it.

NOR flash. NOR architecture connects each cell to the bit-line individually, which makes random reads fast and allows the processor to execute code directly from the array — a property called XIP, execute-in-place. Program operations write at byte or half-word granularity; erase operations are sector-granular, typically in blocks of 64 KB or so, and they take tens of milliseconds. That erase-before-rewrite constraint is the central awkwardness of all flash: you cannot flip a bit from 0 back to 1 without erasing the whole sector. NOR endurance is lower than EEPROM — often ten thousand to a hundred thousand erase cycles per sector. Most microcontrollers with internal flash are NOR-based. External NOR chips appear on SPI or parallel buses when a design needs more code space than the die's internal array provides.

NAND flash. NAND packs cells densely and shares the bit-line between cells in a series string, which reduces die area and therefore cost per bit dramatically. The tradeoff is that NAND cannot be read randomly at the byte level: access is page-granular (typically 2–16 KB per page), and erase is block-granular (tens to hundreds of pages). Bad blocks are expected from the factory and accumulate in use — NAND always needs a controller to manage wear leveling, bad-block tables, and error-correcting codes. NAND is where almost all mass storage lives: the eMMC on a single-board computer, a microSD card, the flash in a USB drive. Endurance per block is typically lower than NOR, and multi-level cell variants (MLC, TLC, QLC) sacrifice further endurance for density. You do not run code directly from NAND; firmware is copied to RAM first.[2] FRAM. Ferroelectric RAM breaks from the charge-storage family entirely: it stores each bit in the polarisation of a ferroelectric layer, so it writes byte by byte at bus speed with no erase step at all. Its endurance, on the order of 10^12 cycles or more, is effectively unlimited for most designs. It appears as standalone serial parts on I²C or SPI and inside some low-power microcontrollers, and it suits data logging and anything written constantly. The cost is density and price per bit, so capacities stay small.

FRAM10^12 EEPROM10^6 NOR flash10^5 NAND flash10^5 Mask ROMn/a Order of magnitude of write cycles per cell, upper end of the ranges above
Fig. 3 — Endurance, plotted as orders of magnitude from the ranges in Table 1. Mask ROM is not written at all, so it has none.

§ 03Reading the Comparison

Line these five up by write granularity and the pattern becomes useful. Mask ROM: no writes (its OTP cousin: once). EEPROM: byte. NOR: sector erase, then byte-granular program. NAND: block erase, page program. Moving down that list, density and raw cost-per-bit improve while the software overhead of managing writes increases. FRAM sits outside that progression: byte writes with no erase step, but at lower density and higher cost per bit.

Endurance follows the inverse curve. EEPROM tolerates far more write cycles than flash, which is why a configuration byte that changes constantly belongs in EEPROM, not in the application-code sectors of internal NOR. A wear-leveled filesystem layer is the wrong answer when a handful of EEPROM bytes and a simple counter will do.

The practical skill is matching workload to type before choosing a part: how often does this data change, how large is it, does the CPU need to fetch instructions from it, and what happens on a partial write if power disappears? Answer those four questions and the right memory type usually picks itself.

An independent explainer on chips, programming and embedded systems. Not a manufacturer, distributor or reseller.

Notes

  1. Endurance figures are quoted per cell, under the manufacturer’s conditions. Treat them as a planning number, not a promise. ↩
  2. If a value changes more than a few times an hour, ask whether it belongs in flash at all. ↩