skip to content

A Redis instance is configured with snapshot persistence only — no append-only file. If the host loses power, how much data is lost, and what exactly determines that amount?

level: middleimportance: must knowfreq 48%

answer

  1. lose everything since the last completed snapshot
  2. window = save points + save duration + failures
  3. content frozen at fork time, not completion
  4. rdb_changes_since_last_save = unprotected writes
  5. temp file + atomic rename => old snapshot survives

basics

~20 s

Everything written since the last completed snapshot. The amount is set by the configured save points, how long each save takes, and the write rate — so it ranges from seconds to the longest save-point interval, potentially an hour.

solid answer

~60 s

You lose every write accepted after the last **successfully completed** snapshot. Snapshots are point-in-time images; there is no incremental record between them, so the exposure is the whole gap. Three things set the size of that gap: - **The save points.** `save 3600 1 / 300 100 / 60 10000` means a quiet server may go an hour between snapshots, while a burst of 10,000 writes forces one within a minute. - **Save duration.** The snapshot reflects the dataset at `fork()` time, not at completion, so writes accepted while the child is writing are already outside it. - **Failures.** If background saves have been failing — full disk, fork denied — the last good snapshot may be far older than the config implies. `rdb_changes_since_last_save` is the live count of unprotected writes and `rdb_last_save_time` the timestamp of the last good one. What you do *not* lose is the previous snapshot: the child writes a temp file and renames it atomically, so a crash mid-save leaves the earlier complete file intact.

code

text · 4 lines
text
$ redis-cli INFO persistence | grep -E 'rdb_last_bgsave_status|rdb_last_save_time|rdb_changes_since_last_save'
rdb_last_bgsave_status:err          # saves have been FAILING
rdb_last_save_time:1723380045       # last good snapshot: two days ago
rdb_changes_since_last_save:1841233 # this many writes would be lost right now

go deeper

for a junior

Say plainly that everything written since the last snapshot is lost, and that the save-point settings decide how big that gap can be.

for a middle

Add that the snapshot freezes at fork time, that save duration widens the gap, and point at rdb_changes_since_last_save as the live measure.

for a senior

Emphasize the failure mode — silently failing saves make the real window unbounded — plus MISCONF write rejection, the temp-file-and-rename safety, and why tightening save points is a poor substitute for a command log.

for a principal

Express it as a recovery-point objective with a cost curve: what each reduction in the window costs in fork pauses and memory, when a different mechanism or a different store is the right answer, and what must be monitored for the stated RPO to be credible.

## What a snapshot protects, and what it does not An RDB file is a point-in-time image. It says: *at this instant, the dataset looked like this*. It carries no record of anything that happened afterwards. So with snapshotting as the only persistence, a sudden power loss costs you **every write accepted since the last completed snapshot** — no partial recovery, no replaying the difference, because nothing recorded the difference. That is the honest shape of the guarantee, and stating it plainly is the point of the question. Redis is not lying to you about it: snapshot-only persistence is explicitly a "lose the last N minutes" configuration, and it is a perfectly good one for data you can rebuild. ## The three factors that size the window **1. The configured save points.** Each `save <seconds> <changes>` line is a trigger condition, and they are alternatives. With the conventional set (`3600 1`, `300 100`, `60 10000`), the *worst case* is bounded by the longest interval whose change threshold you meet. A near-idle server that changes one key an hour is protected only hourly — so it can lose up to an hour of (admittedly sparse) changes. A server taking 10,000 writes a minute snapshots roughly every minute, losing at most about a minute of a very large volume. Notice the asymmetry: low-traffic servers have long windows measured in time, high-traffic servers have short windows containing many writes. **2. When the snapshot's content was frozen.** The child that writes the file forked at time T; the file's contents are the dataset as of T, not as of when the file finished. On a large dataset the write can take tens of seconds. Every command accepted during that period is outside the snapshot even though the snapshot "was running" at the time. The practical version: your effective last-good-point is the last *fork* that completed successfully, not the last moment a save was in progress. **3. Whether saves are actually succeeding.** This is where real incidents live. A disk fills, permissions change, or `fork()` is refused for lack of memory; background saves start failing; the config still says `save 300 100`, so everyone assumes five minutes of exposure, but the last good file on disk is from Tuesday. The instruments: - `rdb_last_bgsave_status` — `ok` or `err` - `rdb_last_save_time` / `LASTSAVE` — Unix time of the last **successful** save - `rdb_changes_since_last_save` — keyspace modifications currently unprotected A climbing `rdb_changes_since_last_save` that never resets is the signature of silently failing persistence. Redis does push back here: with the default `stop-writes-on-bgsave-error yes`, once a background save has failed the server rejects writes with a `MISCONF` error, precisely so a persistence outage cannot masquerade as a healthy server. ## What you do not lose A crash *during* a save does not corrupt or truncate your previous snapshot. The child writes to a temporary file and only `rename()`s it over `dump.rdb` once the complete image, including its CRC64 checksum, is written; rename within a filesystem is atomic. So a mid-save crash leaves the previous complete snapshot on disk. Similarly, a torn or corrupted file is detected on load rather than silently accepted, because of the checksum (unless `rdbchecksum` was disabled). One subtlety: writing and renaming does not by itself guarantee the bytes reached the platter, so a hard power cut can in principle lose a *just-completed* snapshot to the OS page cache. In practice the dominant exposure is the write gap, not this. ## Shrinking the window, and what it costs - **Tighter save points** shorten the gap but add fork pauses and copy-on-write memory episodes; on a large write-heavy instance that tax is continuous while the benefit only materializes during a crash. - **The append-only file** is the real answer when the window must be about a second rather than minutes; that is a different persistence mechanism, not a snapshot tuning knob. - **Replicas do not shrink the durability window in a power loss** of the whole rack, and replication is asynchronous, so a replica may itself be behind at the moment the primary dies. ## The one-sentence version With snapshots only, your loss window is "time since the last successful fork", bounded by your save points, inflated by save duration, and unbounded if saves have been failing — which is why you monitor `rdb_last_bgsave_status` rather than trusting the config file.

  • Does a snapshot include the writes that happen while the snapshot is being written?
    No. The child forked at a moment in time and serializes the copy-on-write view frozen at that instant, so anything the parent accepts afterwards is outside the file even though it arrived while the save was running. Your true recovery point is the fork time of the last successful save, not its completion time.
  • How would you cut a snapshot-only loss window from minutes to about a second?
    Not by tightening save points — snapshotting more often multiplies fork pauses and copy-on-write memory for a still-coarse window. Enable the append-only file with `appendfsync everysec`, which records each write command and flushes once a second, and keep the RDB preamble on so restarts stay fast. Keep save points too, since the snapshot remains your portable backup artifact.
  • What happens if the machine dies halfway through writing a snapshot?
    Nothing is corrupted. The child writes to a temporary file and renames it over dump.rdb only after the complete image and its CRC64 checksum are written, and rename within a filesystem is atomic. You are left with the previous complete snapshot, so the loss window simply extends back to that earlier point.

saying these in an interview costs you the question

  • Saying loss is bounded by the shortest save-point interval regardless of write volume
  • Believing writes made during the save are captured in that snapshot
  • Assuming a crash mid-save corrupts or truncates the existing dump.rdb
  • Trusting the configured save points without checking that saves are succeeding
  • Claiming replicas make snapshot-only persistence lossless

context