Redis · lesson 7 of 14
Beginner
4Intermediate
7- 5 MULTI/EXEC Transactions and the WATCH-Based Optimistic Lock
- 6 Pub/Sub: Channels, Patterns, and the Message That Never Arrives
- 7 RDB vs AOF: What Survives a Hard Kill and What Doesn't
- 8 Replication: A Read-Only Replica, and What WAIT Actually Guarantees
- 9 ACL: a User Restricted to One Key Pattern and One Command
- 12 maxmemory and Eviction: What Redis Throws Away When It's Full
- 13 Cache-Aside with Redis: Stale Reads, Races and Stampedes
Advanced
3Also part of Redis
3RDB vs AOF: What Survives a Hard Kill and What Doesn't
A graceful restart saves your data by default — Redis snapshots on SIGTERM. A hard kill (docker kill, a power loss, an OOM kill) gives it no such chance, and only AOF protects against that. Then: the new BACKUP command family.
By SkillByExample · Published
The same container, the same key, two different shutdowns — and only one of them loses data.
The bug: a hard kill loses recent writes
docker exec redis-lesson redis-cli SET durable "will it survive"
docker restart redis-lesson
# ... container comes back up ...
docker exec redis-lesson redis-cli GET durable
OK
will it survive
That survived — docker restart sends SIGTERM, and Redis performs an RDB save on a graceful
shutdown by default, independent of whatever periodic save points are configured. Now compare
a hard kill:
docker exec redis-lesson redis-cli SET fragile "will this survive a hard kill"
docker kill redis-lesson
docker start redis-lesson
docker exec redis-lesson redis-cli GET fragile
OK
Nothing came back — fragile is gone. docker kill sends SIGKILL, which gives Redis no
chance to run any shutdown code at all. No RDB save happens, so anything written since the
last snapshot — scheduled or shutdown-triggered — is simply lost. This is the real gap in
RDB-only persistence: not “Redis loses data on restart,” but specifically “Redis loses recent
data on a hard crash.”
The fix: AOF, enabled from container start
docker rm -f redis-lesson
docker run -d --name redis-lesson -p 6379:6379 redis:8-alpine --appendonly yes
docker exec redis-lesson redis-cli CONFIG GET appendonly
appendonly
yes
--appendonly yes on the redis-server command line turns on the append-only file from the
moment the server starts — turning it on later with CONFIG SET appendonly yes at runtime
works too, but doesn’t survive a restart unless the config is also persisted, so starting with
it enabled is the more reliable habit for a container that might get recreated.
docker exec redis-lesson redis-cli SET protected "aof should save this"
docker kill redis-lesson
docker start redis-lesson
docker exec redis-lesson redis-cli GET protected
OK
aof should save this
Same hard kill, different outcome — protected survives, because every write was already
logged to the append-only file before the kill happened, not waiting on a snapshot.
The new BACKUP command family (Redis 8.10+)
docker exec redis-lesson redis-cli BACKUP START
docker exec redis-lesson redis-cli BACKUP LIST
OK
/data/backupdir/appendonly.aof.2.base.rdb
BACKUP START opens a backup window and produces a BASE snapshot immediately; BACKUP LIST
shows the files pinned so far — you can start copying the BASE file while Redis keeps
accumulating new writes into its INCR file underneath.
docker exec redis-lesson redis-cli BACKUP SEAL
docker exec redis-lesson redis-cli BACKUP LIST
OK
/data/backupdir/appendonly.aof.2.base.rdb
/data/backupdir/appendonly.aof.2.incr.aof
/data/backupdir/appendonly.aof.manifest
BACKUP SEAL freezes the backup — the INCR file (everything written since START) and a
manifest tying all three files together now appear. Restoring loads BASE + INCR, so the
restored data reflects the state at the seal boundary, not just the earlier snapshot.
docker exec redis-lesson redis-cli BACKUP CLEANUP
docker exec redis-lesson redis-cli BACKUP STATUS
OK
state
idle
error
start_time
0
end_time
0
BACKUP CLEANUP releases the pinned files once they’ve been copied somewhere durable, and
BACKUP STATUS confirms the backup process is back to idle — ready to start the next one.
Practice
1. Check BACKUP STATUS mid-backup, before sealing it.
docker exec redis-lesson redis-cli BACKUP START
docker exec redis-lesson redis-cli BACKUP STATUS
OK
state
incrementing
error
start_time
1789313506
end_time
0
state: incrementing means the BASE snapshot is done and Redis is now accumulating writes
into the INCR file — end_time: 0 confirms it hasn’t been sealed yet.
2. Check the append-only fsync policy currently configured.
docker exec redis-lesson redis-cli CONFIG GET appendfsync
appendfsync
everysec
everysec is the default — fsync once per second, which is fast and still bounds any hard-kill
data loss to roughly the last second of writes, rather than everything since the last RDB
snapshot.
3. Abort an in-progress backup instead of sealing it.
docker exec redis-lesson redis-cli BACKUP ABORT
docker exec redis-lesson redis-cli BACKUP STATUS
OK
state
failed
error
aborted by user
start_time
1789313506
end_time
0
BACKUP ABORT only works before SEAL. The status afterward reports state: failed with the
reason (aborted by user) rather than quietly resetting to idle — the failed state is a
real, inspectable record of what happened to that backup attempt, not just a silent reset.
Next: replication — leader-follower, WAIT, and read-only replicas.