RDB: Point-in-time snapshots

Replaying ten million AOF commands at startup takes forever. The fix is a snapshot. Periodically dump the entire store to a file. On startup, load the snapshot first then replay only the AOF entries since the snapshot.

06-rdb-snapshots/server.py
python
def rdb_save():
    tmp = RDB_PATH.with_suffix(".rdb.tmp")
    payload = {
        "version": 1,
        "saved_at": time.time(),
        "store": STORE,
        "expires": EXPIRES,
    }
    tmp.write_text(json.dumps(payload, separators=(",", ":")))
    os.replace(tmp, RDB_PATH)

Atomic write: tmp file + rename. A reader sees either the old or the new file, never half-written.

06-rdb-snapshots/server.py
python
def cmd_bgsave(args):
    pid = os.fork()
    if pid == 0:
        # Child process: take a snapshot (already COW-isolated) and save
        try:
            rdb_save()
        finally:
            os._exit(0)
    return encode_simple("Background saving started")

BGSAVE forks. The child inherits memory via copy-on-write and takes its time saving. The parent keeps serving traffic.

Copy-on-write during BGSAVE

Fork shares memory pages until one side mutates. The save runs against a stable snapshot.

Every page the parent modifies during the save gets duplicated. Under heavy write traffic, BGSAVE can transiently double memory usage. Production Redis operators tune save intervals to keep this in check.

Quiz: Quiz

Loading practice…