skip to content

A `redis.conf` contains the lines `save 3600 1`, `save 300 100` and `save 60 10000`. Explain precisely what those lines make the server do, and what changes if you replace them all with `save ""`.

level: middleimportance: should knowfreq 45%

answer

  1. save <seconds> <changes>, OR-ed alternatives
  2. dirty counter = rdb_changes_since_last_save
  3. checked in serverCron, always uses BGSAVE
  4. save "" disables automatic snapshots only
  5. no save points => SHUTDOWN does not save

basics

~20 s

Each line is a save point: snapshot in the background if at least that many key changes happened within that many seconds. They are OR-ed, so any satisfied line triggers one. save "" disables automatic snapshots; manual BGSAVE and replica sync still work.

solid answer

~50 s

Each `save <seconds> <changes>` line is a trigger condition: *if at least `<changes>` write operations occurred within `<seconds>` seconds since the last successful save, start a background save.* The three lines are alternatives, not a sequence — whichever fires first wins. So `save 60 10000` covers write bursts, `save 3600 1` guarantees an idle server still snapshots hourly if anything at all changed. Redis checks these conditions in its periodic `serverCron`, roughly ten times a second, comparing `rdb_changes_since_last_save` and the time since `rdb_last_save_time`. The triggered save is always a `BGSAVE`, never the blocking `SAVE`. `save ""` (or removing every `save` line) turns off **automatic** snapshotting only. You can still run `BGSAVE` yourself, replicas can still be seeded with a full sync, and `DEBUG RELOAD` still works — but a crash then loses everything since your last manual snapshot, and `SHUTDOWN` no longer writes one implicitly.

code

text · 13 lines
text
$ redis-cli CONFIG GET save
1) "save"
2) "3600 1 300 100 60 10000"

$ redis-cli INFO persistence | grep -E 'rdb_changes_since_last_save|rdb_last_save_time'
rdb_changes_since_last_save:8421
rdb_last_save_time:1723640119

# disable automatic snapshots, then persist the change to redis.conf
$ redis-cli CONFIG SET save ""
OK
$ redis-cli CONFIG REWRITE
OK

go deeper

for a junior

Explain the seconds/changes pair as a condition and that any one of the lines can trigger a background snapshot.

for a middle

Cover the dirty counter, the OR semantics, that save points always use BGSAVE, and that save "" disables only automatic snapshots.

for a senior

Tie the cadence to the loss window and to the cost side — fork pauses, copy-on-write memory, the failure backoff, and the MISCONF write-rejection behavior.

for a principal

Frame save-point tuning as a latency-versus-loss budget across the fleet, and argue for moving snapshotting to replicas so the primary's tail latency is not hostage to backup policy.

## Anatomy of a save point `save <seconds> <changes>` declares one condition under which Redis should snapshot itself: > if **at least `<changes>` keyspace changes** have accumulated **and at least `<seconds>` seconds** have passed since the last successful save, start a background save. Multiple `save` lines are independent alternatives, evaluated together; the first condition to be satisfied triggers the snapshot. The conventional set expresses a sliding sensitivity: - `save 3600 1` — an almost-idle server still gets an hourly snapshot if even one key changed. - `save 300 100` — moderate activity gets a snapshot every five minutes. - `save 60 10000` — a heavy write burst gets one within a minute. What counts as a "change" is a keyspace modification counter (`dirty` internally, exposed as `rdb_changes_since_last_save` in `INFO persistence`), incremented by write operations. It is not a count of distinct keys or of bytes: one `SET` and one element added to a large hash both bump it. ## How the check runs Redis's `serverCron` runs on the main thread at `hz` times per second (default 10). On each tick it walks the configured save points and compares the counter and the elapsed time since `rdb_last_save_time`. When one matches, it calls `BGSAVE` internally — save points *never* use the blocking `SAVE` path. If a background save or an AOF rewrite child is already running, the trigger is skipped or deferred rather than forking a second child. After a successful save, `rdb_changes_since_last_save` resets to zero and `rdb_last_save_time` advances, so the clock and counter for all save points restart together. There is also a backoff detail worth knowing: if the last background save **failed**, Redis will not retry immediately on every tick; it waits (about five seconds) before attempting another, so a full disk does not produce a fork storm. ## What the numbers actually buy you The save points define your worst-case loss window when snapshots are your only persistence: everything written since the last completed snapshot is gone on a crash. With the set above, a mostly-idle server can lose up to an hour of changes; a busy one loses at most a minute or so. Tightening them does not come free — every extra snapshot is another `fork()` pause and another copy-on-write memory episode on a write-heavy instance, so `save 10 1` on a large busy dataset trades a small loss window for a permanent latency and memory tax. ## Turning it off, and how The idiomatic disable is a single line: ``` save "" ``` which clears the whole list (also usable at runtime: `CONFIG SET save ""`). Deleting the lines has the same effect in a config file. What that changes: - **No automatic snapshots.** Nothing fires on a timer or on write volume. - **`SHUTDOWN` no longer saves implicitly.** With save points configured, a plain `SHUTDOWN` performs a blocking save first; with none configured it exits without saving unless you say `SHUTDOWN SAVE`. - **Manual and system-driven snapshots still work.** `BGSAVE` and `SAVE` are unaffected, replica full-synchronization still produces an RDB stream (or a disk-backed file), and `DEBUG RELOAD` still round-trips through the format. This is a common and legitimate setting for pure caches and for primaries whose backups are taken from a replica — you keep the fork cost off the hot node and snapshot elsewhere. ## Adjusting them safely at runtime `CONFIG SET save "900 1 300 100"` changes the list without a restart; `CONFIG REWRITE` persists it into `redis.conf` so the next start agrees. Verify with `CONFIG GET save`, and watch `rdb_changes_since_last_save` and `rdb_last_save_time` (or `LASTSAVE`) to confirm the new cadence is firing as intended. ## A related trap When a background save fails, the default `stop-writes-on-bgsave-error yes` makes Redis reject writes with a `MISCONF` error until a save succeeds. If you have save points configured on a box with a failing or full disk, the symptom is an apparently healthy Redis that serves reads and refuses writes — check `rdb_last_bgsave_status` before blaming the client.

  • If several save points are configured, are they combined with AND or OR?
    OR. Each line is an independent trigger and the first condition satisfied starts a background save. That is why the conventional set pairs a long interval with a tiny change count and a short interval with a large one — together they cover both idle servers and write bursts.
  • Is disabling automatic snapshots enough to eliminate fork pauses on an instance?
    Not necessarily. `save ""` removes the save-point forks, but an AOF rewrite also forks, and so does a replica full-synchronization when it is disk-backed or even diskless, since Redis still forks a child to produce the stream. To genuinely remove forks you must account for all three sources.
  • What does `rdb_changes_since_last_save` tell you operationally?
    How many keyspace modifications are currently unprotected by any snapshot — that is, exactly what a crash would lose if RDB is your only persistence. Watching it alongside `rdb_last_save_time` tells you whether your save points are firing as designed or whether saves are failing and the number is climbing without bound.

saying these in an interview costs you the question

  • Reading the lines as a schedule ("snapshot every 60 seconds") rather than as conditional triggers
  • Thinking multiple save points must all be satisfied
  • Believing save points trigger a blocking `SAVE`
  • Assuming `save ""` also disables manual `BGSAVE` or replica synchronization
  • Tightening save points on a large write-heavy instance without accounting for fork and copy-on-write cost

context