AOF (Append Only File) is Redis’s other persistence mode. Every write command — SET, DEL, LPUSH, you name it — gets appended to a log file on disk. To restore, Redis replays the log from scratch.
In simple language — think of it like a bank ledger. RDB takes a photo of your account balance once a day. AOF writes down every single deposit and withdrawal. If something goes wrong, you can replay the ledger and reconstruct the exact balance.
Why AOF?
- Durability — depending on fsync policy, you can lose at most 1 second of data (sometimes zero).
- Human-readable — the file is just Redis commands in RESP protocol. You can
catit. - Repairable — if the file gets truncated,
redis-check-aof --fixcan salvage what’s left.
The cost — bigger files, slower restarts (replay every command), and more disk I/O during normal operation.
The fsync policies
Here’s where it gets interesting. Writing to a file goes through the OS buffer cache. To actually flush to disk you need fsync(). AOF lets you pick how often that happens.
fsync after every write
→ slowest, safest
data loss: ~0
fsync once per second
→ default, balanced
data loss: ≤ 1s
let the OS decide
→ fastest, riskiest
data loss: ~30s
everysec is the sweet spot. You’d only pick always if you absolutely cannot lose a single write (financial logs maybe), and no if Redis is just a cache and you don’t really care.
# redis.conf
appendonly yes
appendfsync everysec # always | everysec | no
The rewrite problem
Here’s the issue with an append-only log — it grows forever. If you INCR counter a million times, the log has a million lines. But the final state is just counter = 1000000.
Redis fixes this with BGREWRITEAOF. It forks a child process (same COW trick as RDB), walks the current dataset, and writes the minimum set of commands needed to reconstruct it. Then it swaps the new file in.
BGREWRITEAOF # manual trigger
Auto-rewrite config:
auto-aof-rewrite-percentage 100 # rewrite when AOF is 100% bigger than last rewrite
auto-aof-rewrite-min-size 64mb # but only if it's at least 64mb
What’s in the file?
Just RESP-encoded commands. Open it up:
*2
$6
SELECT
$1
0
*3
$3
SET
$3
foo
$3
bar
That’s SELECT 0 followed by SET foo bar. Replay this top to bottom and you get the dataset back.
Tradeoffs at a glance
| AOF wins | AOF loses |
|---|---|
| Better durability | Larger file size |
| Easy to repair / inspect | Slower restart (must replay) |
| Tunable fsync | More disk I/O during runtime |
For most production setups, you’d run AOF alongside RDB — see Hybrid Persistence for the recommended combo.