RDB vs. AOF: Choosing the Right Strategy for Your Use Case
AI generated
SET
TTL
Redis · Persistence · RDB · AOF
RDB vs. AOF
Choosing the Right Strategy for Your Use Case

RDB and AOF solve the same underlying problem, losing in-memory data on a crash, with completely different tradeoffs between recovery time, data loss window, and resource demand. Anyone who understands both mechanisms and knows when combining RDB and AOF pays off makes a persistence decision that fits the actual use case, instead of relying on default values.

15 min read RDB · AOF · mixed persistence · recovery time Redis 6.x · 7.x

1. Why RDB vs. AOF Is Not a Formality

The decision between RDB vs. AOF is never made deliberately in many Redis setups, and instead just runs along with whatever defaults the distribution shipped. That is risky, because both mechanisms deliver fundamentally different guarantees: RDB saves periodic full states in a compact file, AOF logs every single write operation and thus allows a much tighter loss window. Anyone who never explicitly weighs RDB vs. AOF implicitly inherits the risk tolerance the distribution maintainer considered appropriate for a generic use case, not their own.

The difference only becomes tangible once you picture concrete failure scenarios: a process crash from the OOM killer, a power outage in the data center, an accidental container restart triggered by the orchestration system. Each of these scenarios makes RDB and AOF behave differently, both in terms of data loss and time to recovery. These two quantities, loss window and recovery time, are the real decision basis for RDB vs. AOF, not abstract best-practice recommendations.

This article puts both mechanisms side by side, shows how to combine them, and gives concrete criteria for cache scenarios on one hand and durable store scenarios on the other. The technical details of RDB snapshots and AOF persistence individually are covered in the two preceding articles in this series.

2. Core Mechanics Compared Head to Head

RDB works on the point-in-time snapshot principle: at configurable moments, controlled via save directives, Redis forks a child process that writes the entire memory content as a binary file. Between two snapshots there is no logging of individual operations, the state between snapshots is simply lost on a crash. AOF, in contrast, works on the write-ahead-log principle: every write command, depending on the appendfsync setting, gets written almost immediately to a continuously growing file.

This different core mechanic has direct consequences for file size: an RDB file is always proportional to the size of the actual dataset, regardless of how many write operations occurred in between. An AOF file without regular rewrites, on the other hand, can grow substantially larger than the actual dataset if the same key is overwritten frequently, because every single operation stays logged until a BGREWRITEAOF compacts the history.

Criterion RDB AOF
Loss window Minutes (depends on save points) Up to 1 second (everysec)
File size Compact, proportional to dataset Larger, grows until rewrite
Recovery time Fast, linear read Slower, command replay
Runtime overhead Only during BGSAVE Continuous, every write
Compatibility Forward-compatible More robust across versions

3. Recovery Time: What Really Happens on Restart

On restart with RDB alone, Redis reads the binary file sequentially and builds the internal data structures directly from the serialized values. This process scales nearly linearly with file size and is independent of how many write operations originally led to the dataset. A 10 GB RDB snapshot loads in a predictable, measurable time, typically ranging from a few seconds to low single-digit minutes, depending on disk speed and data types.

With AOF, Redis instead has to re-execute every single logged command, as if a client were sending them one after another. With a freshly compacted AOF file and a recent base file, this is barely slower than RDB, because the base file exists in RDB format and only the small incremental file is actually replayed command by command. Without regular rewrites, however, recovery time can increase substantially, because millions of individual commands must be processed instead of a compact snapshot.

In practice this means: AOF recovery time depends directly on rewrite discipline. A well-configured auto-aof-rewrite-percentage with regular rewrites keeps incremental files small and recovery time close to that of RDB. If rewrites are neglected, for example because auto-aof-rewrite-percentage is set too high, recovery time grows noticeably, especially for datasets with a high write rate on the same keys.


# Compare startup time with RDB-only vs AOF-heavy configuration
time redis-server --dbfilename dump.rdb --appendonly no --daemonize no &
sleep 5 && redis-cli SHUTDOWN NOSAVE

time redis-server --appendonly yes --appenddirname appendonlydir --daemonize no &
sleep 5 && redis-cli SHUTDOWN NOSAVE

# Check AOF file sizes to estimate replay cost
du -sh /var/lib/redis/appendonlydir/*.incr.aof
du -sh /var/lib/redis/appendonlydir/*.base.rdb

4. Realistically Assessing the Data Loss Window

A blanket comparison of loss windows often obscures the actual risk exposure. With RDB and save 60 10000 as the most aggressive configured save point, up to almost a minute of write operations can be lost in the worst case, as long as fewer than 10,000 changes occurred within that minute and no earlier save point applied. Under very high, constant write load, however, this point triggers more often, which reduces the effective loss window in practice.

With AOF and appendfsync everysec, the loss window stays constant at a maximum of one second, regardless of write rate, because the background thread syncs once per second on a fixed schedule independent of the number of operations. That makes AOF loss windows considerably more predictable than RDB loss windows, which depend on the actual write rate at the moment of the crash and therefore vary more.

For a solid risk assessment, the loss window should be thought of not just in time but in business impact: losing 60 seconds of session data usually just means some users have to log in again. Losing 60 seconds of order data in a checkout flow potentially means lost revenue and inconsistent state between Redis and downstream systems such as a relational database.


# Compare the effective loss window of both mechanisms via INFO
redis-cli INFO persistence | grep -E "rdb_changes_since_last_save|rdb_last_save_time|aof_last_write_status"
# rdb_changes_since_last_save:8421   -> unsaved writes since last RDB snapshot
# rdb_last_save_time:1721739600
# aof_last_write_status:ok           -> AOF write path healthy

# Estimate the RDB loss window in seconds right now
echo "$(( $(date +%s) - $(redis-cli LASTSAVE) )) seconds since last RDB snapshot"

5. Resource Demand: Memory, CPU, and Disk I/O

RDB uses resources in bursts: during a BGSAVE, memory demand briefly rises via copy-on-write, and CPU load comes from the fork plus, optionally, LZF compression. Outside these windows, RDB causes practically no ongoing load. AOF, by contrast, uses resources continuously: every write generates an extra write() syscall, and depending on the appendfsync setting, a regular or even permanent fsync() overhead comes on top.

Disk I/O is structurally higher with AOF than with plain RDB, because writes happen continuously rather than only at set points in time. On systems with a limited I/O budget, such as cloud instances with throttled IOPS, this sustained-load character of AOF can weigh more heavily than the bursty but more intense load of RDB. Capacity planning should therefore account not just for the peak load of a BGSAVE, but also for the continuous baseline I/O of AOF when both mechanisms run in parallel.

A practical way to make the actual resource difference visible is a short observation with system tools during a typical load phase. Elevated %iowait values during continuous AOF writes, compared to brief, intense I/O spikes during a BGSAVE, show the different resource characteristics of both mechanisms very clearly.


# Observe disk I/O characteristics: continuous AOF vs bursty RDB
iostat -x 2 10 | grep -E "Device|sda"
# %util spikes briefly during BGSAVE, stays elevated continuously
# with appendfsync always under sustained write load

# Compare memory growth during a BGSAVE (copy-on-write effect)
watch -n 1 'redis-cli INFO memory | grep -E "used_memory_human|mem_fragmentation_ratio"'

6. Both Together: Configuring Mixed Persistence Correctly

Most production Redis setups do not enable RDB or AOF exclusively, but both together, often called mixed persistence or hybrid persistence. AOF handles primary durability with a tight loss window, while RDB additionally provides fast, portable backups, for example to copy easily to another server or to use for replication bootstrapping. An additional benefit: since Redis 4, the base file of an AOF rewrite can itself be in RDB format, so the compaction step benefits from the RDB serialization that already exists.

With mixed persistence enabled, Redis prefers loading AOF data on startup, as long as appendonly yes is set, because it guarantees the tighter loss window. The RDB file in this setup mainly serves as a backup artifact and replication base, not as the primary recovery source. This combination essentially delivers the best of both worlds: the tight durability guarantee of AOF for normal operation and the compact, portable RDB file for backup and migration scenarios.


# redis.conf - Mixed persistence: RDB + AOF together

# AOF as the primary durability mechanism
appendonly yes
appendfsync everysec

# RDB save points still active for portable backups
save 900 1
save 300 10

# AOF rewrite uses RDB format for the base file (default since Redis 4)
aof-use-rdb-preamble yes

# On startup, AOF takes precedence over RDB if both are present
# (this is Redis's built-in default behavior, not a separate directive)

7. Cache-Only Scenarios: When Persistence Barely Matters

For pure cache use cases, where Redis can always be repopulated from a source such as a relational database or an external service, the persistence decision is much more relaxed. What matters here is primarily how expensive a cache miss is after a restart, not whether data can be lost, because a loss simply means the cache needs to be refilled. In such scenarios, RDB with moderate save points, or even completely disabled persistence, is often enough.

The distinction between cold and warm restart matters here: without any persistence, Redis starts completely empty, which for large cache sizes can cause a noticeable thundering herd effect on the backend system, because suddenly every request lands as a cache miss on the data source. An RDB snapshot, even with a moderate loss window, substantially mitigates this problem, because the cache stays mostly warm after a restart instead of having to be rebuilt from scratch.

8. Durable Store Scenarios: When AOF Is Mandatory

As soon as Redis is no longer just a cache but the primary or sole data source for a business process, for example queues for asynchronous jobs, rate-limiting counters with billing relevance, or session stores whose loss kicks users out of an ongoing checkout process, AOF with appendfsync everysec becomes practically mandatory. The tight loss window of at most one second substantially reduces the risk of inconsistent state between Redis and connected systems.

For use cases with even stricter requirements, such as financial transactions or legally mandated traceability, even appendfsync always can be justified, despite the noticeable latency overhead. In such cases, it often pays off to make an architectural decision to route critical write paths through dedicated Redis instances with always, while less critical workloads run on separate instances with everysec, so as not to force the entire system's latency characteristics to match the strictest use case.

9. A Decision Framework for Your Own Use Case

The RDB vs. AOF decision can be structured around three questions: first, how expensive is losing the last seconds to minutes of write operations for the business? Second, how critical is a fast recovery time after a restart, for example within a service level agreement? Third, how much extra resource demand from continuous AOF writing is acceptable within the current infrastructure budget?

As a rule of thumb: pure caches with a cheap backend source get by with RDB alone or even no persistence at all. Anything where Redis is the primary data source should use AOF with at least everysec. And practically every production setup benefits from mixed persistence, because the RDB component provides additional backup and migration flexibility without compromising the durability guarantee of AOF.


#!/usr/bin/env bash
# persistence_decision_check.sh - Quick decision-support snapshot
set -euo pipefail

echo "--- Current persistence configuration ---"
redis-cli CONFIG GET appendonly
redis-cli CONFIG GET appendfsync
redis-cli CONFIG GET save

echo "--- Current risk exposure ---"
redis-cli INFO persistence | grep -E \
  "rdb_changes_since_last_save|aof_enabled|aof_last_bgrewrite_status"

# Decision rule of thumb:
#   Pure cache, cheap backend refill -> RDB only is usually fine
#   Redis as primary data source     -> AOF with at least everysec
#   Most production setups           -> RDB + AOF together (mixed)

Mironsoft

Redis operations, persistence strategy, and backup infrastructure

RDB or AOF, or both together?

We assess your use case based on loss window, recovery time, and resource budget, and configure a persistence strategy that fits your actual requirements instead of default values.

Risk Analysis

Weigh loss window against business impact

Mixed Persistence Setup

Configure RDB and AOF together for maximum flexibility

Recovery Testing

Measure restart times under realistic data volumes

10. Summary

The RDB vs. AOF question has no universal answer, it depends on loss window, required recovery time, and available resource budget. RDB delivers compact, fast-loading snapshots with a loss window in the minutes range and bursty resource use. AOF delivers a loss window of at most one second with continuous but well-controllable resource use. For most production setups, combining both, mixed persistence, is the most robust choice.

Cache-only scenarios with a cheap backend source usually get by with RDB alone. Durable store scenarios, where Redis is the primary data source, should use AOF with at least everysec. The RDB vs. AOF decision should always be made and documented explicitly, instead of implicitly following distribution defaults.

RDB vs. AOF: the Essentials at a Glance

Loss Window

RDB: minutes, depending on save points. AOF: up to 1 second with everysec.

Recovery Time

RDB loads linearly and fast. AOF depends heavily on current rewrite discipline.

Mixed Persistence

AOF for durability, RDB for portable backups, both together recommended for most setups.

Rule of Thumb

Cache: RDB usually enough. Primary data source: AOF with at least everysec is mandatory.

11. FAQ: RDB vs. AOF

1Is AOF fundamentally better than RDB?
Not fundamentally. AOF has a tighter loss window but costs more resources. RDB is more compact but has a larger window.
2Should I enable RDB and AOF together?
For most production setups, yes, as mixed persistence combining the benefits of both mechanisms.
3Which mechanism loads preferentially on restart?
With appendonly yes, Redis prefers AOF data because of its tighter loss window.
4Is RDB alone enough for a pure cache?
Usually yes, as long as the backend source can be queried again cheaply.
5When is AOF with everysec mandatory?
When Redis is the primary data source for a business process, such as queues or session stores.
6Why is AOF recovery time variable?
It depends on the size of the incremental file since the last rewrite.
7What is aof-use-rdb-preamble?
Makes the AOF base file get written in compact RDB format, default since Redis 4.
8Does AOF put more load on the CPU?
Continuously yes, RDB loads CPU only in bursts during BGSAVE.
9How do I find the acceptable loss window?
Assess through business impact, not through technical default values.
10Can persistence differ per data type?
Not directly within one instance, splitting across separate instances is the better approach.