RDB Snapshots
An RDB snapshot is a compact, point-in-time binary dump of your entire Redis dataset, written to a single file on disk (by default dump.rdb). It’s one of the two persistence mechanisms Redis offers — the other being the AOF write log — and it’s what lets an in-memory database survive a restart, a crash, or a planned migration without losing everything. Understanding exactly when a snapshot happens and what it does and doesn’t protect you from is essential before you rely on Redis for anything you can’t afford to lose.
Overview / How RDB Snapshots Work
Redis keeps your entire keyspace in RAM. RDB persistence periodically serializes that in-memory data structure — strings, hashes, lists, sets, sorted sets, everything — into a single compressed binary file. Because it’s a snapshot, it represents the dataset exactly as it looked at one moment in time, not a continuous record of every write.
There are two ways a snapshot gets written. SAVE performs the dump synchronously on the main thread: Redis stops responding to any other command until the entire dataset has been written to disk. Because Redis is single-threaded, this means every client is blocked for the duration — on a large dataset, that could be seconds or more of total unavailability. BGSAVE instead forks a child process. The operating system’s fork() gives the child a copy-on-write view of the same memory pages the parent is using, so the child can walk that memory and write it to disk while the parent keeps serving reads and writes on the main thread. If a client writes to a key while the child is still saving it, the kernel copies just that memory page before the change is applied, so the child’s view of the data stays consistent with the moment the fork happened. This copy-on-write behavior is why a very write-heavy workload during a long BGSAVE can cause a real memory spike — every page that gets modified while the snapshot is in progress gets duplicated.
Snapshots don’t only happen when you ask for one. Redis can trigger a BGSAVE automatically based on save points configured in redis.conf (or seen via CONFIG GET save), expressed as pairs of seconds and number-of-changes — for example, “save after 3600 seconds if at least 1 key changed, or after 300 seconds if at least 100 keys changed, or after 60 seconds if at least 10000 keys changed.” Redis checks these thresholds as part of its normal periodic housekeeping (the same background cron-like cycle that also does lazy expiration cleanup), and fires a BGSAVE the first threshold it satisfies.
Crucially, RDB is a snapshot, not a log. If Redis crashes one second after the last successful save, every write made in that one second is gone. That’s the fundamental trade-off against AOF, which logs every write and can be configured to fsync on every command for near-zero data loss at the cost of a larger file and slower restarts. Most production setups that care about durability run both: RDB for fast, compact backups and quick restarts, AOF for a tighter durability window.
Syntax
The core RDB commands take no arguments beyond the command name itself:
SAVE
BGSAVE
LASTSAVE
SAVE— synchronously writes the dataset to disk and blocks all clients until it finishes. ReturnsOKon success.BGSAVE— forks a child process to write the dataset to disk in the background. Returns the status stringBackground saving startedimmediately, before the write is complete.LASTSAVE— returns the Unix timestamp of the last time a snapshot was successfully written to disk, whether triggered manually or automatically.CONFIG GET save— reports the currently configured automatic save points.CONFIG GET dir/CONFIG GET dbfilename— report where the RDB file is written and what it’s named, together forming the full path.INFO persistence— reports live persistence state, including whether a background save is in progress and whether the last one succeeded.
Examples
Example 1: Manual snapshot with SAVE and checking LASTSAVE
SET user:1001:name "Ada"
SET user:1002:name "Grace"
DBSIZE
SAVE
LASTSAVE
Output:
OK
OK
(integer) 2
OK
(integer) 1754800000
Two keys are written, DBSIZE confirms there are two keys in the current database, and SAVE blocks until the full dataset — small here, but this scales to however many keys exist — is flushed to dump.rdb. LASTSAVE then reports the Unix timestamp of that write; the exact number will differ every time you run this, since it reflects the moment the snapshot completed.
Example 2: Non-blocking snapshot with BGSAVE and checking status
SET session:abc123 "active"
SET session:def456 "active"
BGSAVE
INFO persistence
Output:
OK
OK
Background saving started
# Persistence
loading:0
rdb_changes_since_last_save:0
rdb_bgsave_in_progress:0
rdb_last_save_time:1754800012
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:0
rdb_current_bgsave_time_sec:-1
aof_enabled:0
...
BGSAVE returns immediately with a status message rather than waiting for the write to finish. INFO persistence (trimmed here — the real reply has many more fields) is how you actually confirm the save completed: rdb_bgsave_in_progress:0 means no save is currently running, and rdb_last_bgsave_status:ok confirms the most recent one succeeded rather than failing silently in the background.
Example 3: Finding where the snapshot lives and its trigger rules
CONFIG GET save
CONFIG GET dir
CONFIG GET dbfilename
Output:
1) "save"
2) "3600 1 300 100 60 10000"
1) "dir"
2) "/data"
1) "dbfilename"
2) "dump.rdb"
The save value lists the automatic snapshot thresholds as pairs — here, snapshot after 1 change in an hour, 100 changes in 5 minutes, or 10,000 changes in a minute, whichever comes first. dir combined with dbfilename gives you the full path to the snapshot file on this server; your own instance’s dir value will likely be different depending on how it was started.
How It Works Step by Step
When a BGSAVE runs (directly, or triggered automatically by a save point), Redis does the following:
- The main thread calls
fork(). The OS creates a child process sharing the parent’s memory pages via copy-on-write — this is fast because no memory is actually duplicated yet. - The child process walks every key in every database and serializes it into the RDB binary format, writing to a temporary file.
- Meanwhile, the parent process keeps handling client commands normally on the main thread. If a client modifies a page the child still needs to read, the kernel duplicates that page before applying the write, so the child’s snapshot remains a consistent view of the dataset as of the fork moment.
- Once the child finishes writing the temp file, it atomically renames it over the previous
dump.rdb, then exits. The parent detects the child’s exit and updates its internal state, which is whatrdb_last_bgsave_statusandLASTSAVEreflect.
A plain SAVE skips the fork entirely and does this same serialization work directly on the main thread — simpler, but every other command has to wait.
Common Mistakes
Mistake 1: Running SAVE on a large, busy production database. Because Redis is single-threaded, SAVE freezes every client — reads, writes, everything — until the full dataset is written. On a dataset of any real size this can mean seconds of total downtime for every connected application. Use BGSAVE, or let the configured save points trigger it automatically, instead.
Mistake 2: Treating RDB as a zero-data-loss guarantee. A snapshot only captures data up to the moment it ran. If your save points are 3600 1 (once an hour) and the server crashes 59 minutes after the last snapshot, everything written in that window is gone — there is no partial recovery. If your workload can’t tolerate that gap, you need AOF (optionally with appendfsync everysec or stricter) alongside RDB, not RDB alone.
Mistake 3: Disabling snapshotting without enabling any other persistence. It’s possible to turn off automatic snapshots entirely (illustrated below, not run against this lesson’s server since it mutates global config):
CONFIG SET save ""
Doing this with AOF also disabled means a restart or crash wipes the dataset completely — there is nothing left to reload from. If you deliberately disable RDB (for example, on a pure cache where every value is disposable and rebuildable from a source of truth), that’s a valid choice — but make it deliberately, not by accident.
Best Practices
- Prefer
BGSAVE, or automaticsave-point triggers, over manualSAVEon any server handling live traffic. - Combine RDB with AOF when you need both fast restarts and a tight durability window — RDB for compact backups and quick recovery, AOF for minimizing the data-loss gap.
- Check
rdb_last_bgsave_statusandrdb_last_save_timefromINFO persistenceas part of routine monitoring — a background save can fail (for example, if disk space runs out) without anything else in your application noticing. - Make sure the host has enough free memory headroom for the copy-on-write growth that can happen during a
BGSAVEon a write-heavy workload — a fork that runs out of memory can fail or trigger the OS’s out-of-memory killer. - Copy the
dump.rdbfile to offsite/versioned storage on a schedule, and periodically test restoring from a copy — an untested backup is not a backup. - Use
CONFIG GET dirandCONFIG GET dbfilenameto confirm exactly where a given instance writes its snapshot before building backup tooling around it.
Practice Exercises
- Set five different keys of your choosing, then run
BGSAVEfollowed byINFO persistence. Find therdb_changes_since_last_savefield before and after — it should reset to 0 once the background save completes. - Run
CONFIG GET dirandCONFIG GET dbfilenameagainst your own Redis instance and confirm you can locate the actualdump.rdbfile on disk using those two values together. - Scenario: you’re running a leaderboard cache that can be fully rebuilt from your primary database in under a minute if lost. Decide whether you’d keep the default
savepoints, tighten them, or disable RDB entirely in favor of relying on the rebuild — write down your reasoning before checking it against the trade-offs described above.
Summary
- RDB snapshots are point-in-time binary dumps of the whole dataset, written to a single file such as
dump.rdb. SAVEis synchronous and blocks the whole server;BGSAVEforks a child process so writes and reads keep flowing during the save.- Automatic snapshots fire based on the
saveconfiguration — pairs of seconds and number-of-changed-keys thresholds. LASTSAVEandINFO persistenceare how you verify a snapshot actually happened and succeeded.- RDB alone always has a data-loss window equal to the time since the last successful snapshot — pair it with AOF if that window is too wide for your use case.
CONFIG GET dir/dbfilenametell you exactly where the snapshot file lives on disk.
