100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Programming

EEPROM and Persistent Storage

How to store data that survives power loss on Arduino using the built-in EEPROM, plus the wear limits, techniques, and modern alternatives for persisting settings and logs.

Communication & LibrariesIntermediate9 min readJul 10, 2026
Analogies

Why Persistent Storage Matters

Every variable in an Arduino sketch lives in SRAM, which is wiped the instant power is removed or the board resets. That is fine for temporary values, but many projects need memory that survives a reboot: a thermostat's set temperature, a device's calibration offsets, a running counter, or a WiFi configuration. EEPROM (Electrically Erasable Programmable Read-Only Memory) is the classic answer. On an ATmega328-based Uno it provides 1024 bytes of non-volatile storage built into the chip, readable and writable byte by byte from your sketch and retained for years without power.

🏏

Cricket analogy: SRAM losing data on reset is like a scoreboard wiped at stumps; EEPROM is the official scorebook that preserves the innings permanently.

The EEPROM Library API

The built-in EEPROM library gives you byte-level access. EEPROM.read(address) returns a single byte and EEPROM.write(address, value) stores one, where address ranges from 0 to the chip's size minus one. Because most data is larger than a byte, the library adds EEPROM.put(address, data) and EEPROM.get(address, data) templates that serialize any type, including floats and structs, across consecutive bytes automatically. Crucially, put() performs an update rather than a blind write: it reads each byte first and only writes if the value changed, which protects the memory from unnecessary wear.

🏏

Cricket analogy: put() checking before writing is like a batter reviewing the field before playing a shot, acting only when it actually changes the outcome.

cpp
#include <EEPROM.h>

struct Settings {
  float setpoint;
  int   brightness;
  bool  celsius;
};

void saveSettings(const Settings& s) {
  EEPROM.put(0, s);   // writes only bytes that changed
}

Settings loadSettings() {
  Settings s;
  EEPROM.get(0, s);   // reconstructs the struct from EEPROM
  return s;
}

void setup() {
  Serial.begin(9600);
  Settings s = loadSettings();
  Serial.println(s.setpoint);
}

EEPROM cells wear out. Each location is rated for roughly 100,000 write/erase cycles. A sketch that writes a value inside loop() every few milliseconds can destroy a cell in hours. Always write only when data actually changes (use put/update), and never put a raw EEPROM.write() in a tight loop.

Wear, Validity, and Wear Leveling

Because writes are limited, two practices are essential. First, guard against reading garbage on a brand-new chip, whose bytes default to 0xFF: store a known 'magic' marker byte and only trust the saved data if it matches, otherwise fall back to defaults. Second, for data that changes often, such as a boot counter, spread writes across many addresses (wear leveling) so no single cell is exhausted. You cycle through a block of locations, writing each new value to the next slot, so 100,000 cycles per cell multiplies into far more total writes for the counter as a whole.

🏏

Cricket analogy: A magic marker byte validating data is like checking the ball is the right one before an over; wrong marker, and you don't trust the read.

On the ESP32 and ESP8266 there is no true internal EEPROM; the Arduino EEPROM library there is an emulation backed by flash, and you must call EEPROM.begin(size) first and EEPROM.commit() after writing. The modern Preferences library is the recommended key-value alternative on those boards.

When to Use Something Bigger

EEPROM's kilobyte is perfect for settings and small counters, but not for logs, datasets, or files. When you need to record thousands of sensor samples or store a web page, move up to an SD card over SPI, which offers gigabytes and a real filesystem through the SD library. On ESP32 boards, the SPIFFS or LittleFS filesystems put a small filesystem in onboard flash. Matching the storage medium to the data size, EEPROM/Preferences for tiny persistent settings and SD/flash filesystems for bulk data, keeps projects both reliable and cost-effective.

🏏

Cricket analogy: Choosing EEPROM vs an SD card is like picking a pocket notebook for the batting order but a full ledger for a whole season's stats.

  • SRAM is volatile; EEPROM provides non-volatile, byte-addressable storage that survives power loss.
  • An ATmega328 Uno has 1024 bytes of internal EEPROM.
  • EEPROM.read/write handle single bytes; EEPROM.get/put serialize any type, and put() writes only changed bytes.
  • EEPROM cells tolerate about 100,000 writes, so never write in a tight loop.
  • Use a magic marker byte to validate data and fall back to defaults on a fresh chip (bytes default to 0xFF).
  • Wear leveling spreads frequent writes across many addresses to extend total endurance.
  • ESP32/ESP8266 emulate EEPROM in flash (needing begin/commit) and prefer the Preferences library; use SD/flash filesystems for bulk data.

Practice what you learned

Was this page helpful?

Topics covered

#Programming#ArduinoProgrammingStudyNotes#EEPROMAndPersistentStorage#EEPROM#Persistent#Storage#Matters#StudyNotes#SkillVeris#ExamPrep