Backup and Restore Strategies for Production Redis Instances
AI generated
SET
TTL
Redis · Backup · Restore · Disaster Recovery
Backup and Restore Strategies
for Production Redis Instances

Persistence mechanisms like RDB and AOF protect against a process crash, but not against a failed disk, a deleted server, or a human mistake. A solid backup strategy for Redis copies snapshots consistently, automates retention, regularly tests restores, and keeps at least one copy outside the production infrastructure.

14 min read RDB copy · automation · restore test · off-site Redis 6.x · 7.x

1. Why Persistence Does Not Replace a Backup

A common misconception is treating RDB snapshots or AOF persistence as an already complete backup strategy. Both mechanisms protect against the same scenario: a process restart, where the memory content would otherwise be completely lost. Neither, however, protects against a failed disk, an accidentally deleted server, a corrupted hard drive, or a human error such as a mistakenly executed FLUSHALL, which gets persisted just as reliably as any other operation.

A real backup strategy differs from plain persistence in three crucial ways: it keeps multiple points in time, not just the latest state, it lives physically separate from the production instance, and it gets regularly tested for recoverability. An RDB snapshot sitting on the same disk as the running Redis instance is lost in a hardware failure just as much as the dataset itself.

This article covers the practical implementation of a robust backup strategy: consistently copying RDB and AOF files, automation with a retention policy, regular restore tests, and an off-site component. The technical fundamentals of RDB and AOF themselves are covered in the preceding articles in this series.

2. Copying RDB Files Consistently

Simply copying an RDB file with cp while the server is running sounds simple at first, but carries a consistency risk: if an automatic BGSAVE overwrites the file at exactly that moment, the copy could catch an inconsistent intermediate state. Redis writes internally through a temporary file and only renames atomically, which practically rules out the risk of a half-written file, but a backup process should still not rely on random timing.

The more robust method is to explicitly force a fresh, guaranteed-complete snapshot before copying: call redis-cli BGSAVE, wait for completion by polling rdb_bgsave_in_progress, and only then copy the file. That guarantees the backup contains exactly the state at the time of the backup run, instead of an older, potentially hours-old snapshot from an automatic save point.


#!/usr/bin/env bash
# rdb_backup.sh - Force a fresh, consistent RDB snapshot and copy it out
set -euo pipefail

RDB_DIR="/var/lib/redis"
RDB_FILE="dump.rdb"
BACKUP_DIR="/var/backups/redis"
TIMESTAMP="$(date +%Y%m%d-%H%M%S)"

mkdir -p "$BACKUP_DIR"

# Trigger a fresh snapshot and wait for it to finish
redis-cli BGSAVE
while [[ "$(redis-cli INFO persistence | grep rdb_bgsave_in_progress | cut -d: -f2 | tr -d '\r')" == "1" ]]; do
  sleep 1
done

STATUS="$(redis-cli INFO persistence | grep rdb_last_bgsave_status | cut -d: -f2 | tr -d '\r')"
if [[ "$STATUS" != "ok" ]]; then
  echo "[ERROR] BGSAVE failed, aborting backup" >&2
  exit 1
fi

# Copy the now-guaranteed-consistent file
cp "${RDB_DIR}/${RDB_FILE}" "${BACKUP_DIR}/dump-${TIMESTAMP}.rdb"
gzip "${BACKUP_DIR}/dump-${TIMESTAMP}.rdb"
echo "[OK] Backup written: ${BACKUP_DIR}/dump-${TIMESTAMP}.rdb.gz"

3. Backing Up AOF Directories: the Specifics

With AOF persistence enabled, the dataset to back up is no longer a single file, but the entire appendonlydir directory with manifest, base, and incremental files. A backup that copies only individual files from this directory, instead of the whole directory tree including the manifest, leads to an inconsistent state on restore, because the manifest describes the exact mapping between base and incremental files.

Analogous to RDB backups, it is advisable to force an explicit BGREWRITEAOF before copying, to guarantee a fresh, compact base file instead of also backing up a potentially large incremental file. It is important not to miss any file while copying the complete directory, in case Redis creates new incremental files between the start and end of the copy, for example through a rewrite running in parallel. An atomic filesystem snapshot, for instance via LVM or ZFS, avoids this problem entirely.


#!/usr/bin/env bash
# aof_backup.sh - Backup the complete AOF directory consistently
set -euo pipefail

AOF_DIR="/var/lib/redis/appendonlydir"
BACKUP_DIR="/var/backups/redis"
TIMESTAMP="$(date +%Y%m%d-%H%M%S)"

mkdir -p "$BACKUP_DIR"

# Force a fresh, compact base file before copying
redis-cli BGREWRITEAOF
while [[ "$(redis-cli INFO persistence | grep aof_rewrite_in_progress | cut -d: -f2 | tr -d '\r')" == "1" ]]; do
  sleep 1
done

# Copy the entire directory (manifest + base + increment files together)
tar -czf "${BACKUP_DIR}/aof-${TIMESTAMP}.tar.gz" -C "$(dirname "$AOF_DIR")" "$(basename "$AOF_DIR")"
echo "[OK] AOF backup written: ${BACKUP_DIR}/aof-${TIMESTAMP}.tar.gz"

4. Automating Backup Jobs: Cron, Systemd Timers, Retention

Manual backups are worthless for production operations because they inevitably get forgotten. Automation via cron or, preferred on modern Linux distributions, via systemd timers ensures backups run reliably at fixed times, independent of human memory. A systemd timer offers built-in logging via journalctl over cron, plus the Persistent=true option, which automatically catches up on missed runs after a server restart.

Just as important as execution is a clear retention policy: without automatic deletion of old backups, the backup partition eventually fills up, potentially with fatal consequences if that also causes new backups to fail. A proven schedule keeps daily backups for two weeks, weekly backups for three months, and monthly backups for a year, which keeps both short-term errors and older data states recoverable without consuming unlimited storage.


# /etc/systemd/system/redis-backup.service
[Unit]
Description=Redis RDB backup job
After=redis.service

[Service]
Type=oneshot
ExecStart=/usr/local/bin/rdb_backup.sh
User=redis

# /etc/systemd/system/redis-backup.timer
[Unit]
Description=Run Redis backup daily at 02:30

[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true

[Install]
WantedBy=timers.target

# Retention cleanup: keep 14 daily, 12 weekly, 12 monthly backups
find /var/backups/redis -name "dump-*.rdb.gz" -mtime +14 -delete

5. Checking Backups for Consistency

A backup that was merely copied successfully is not yet a verified backup. After copying, every RDB file should be checked for structural consistency with redis-check-rdb before it is marked valid. The tool reads the file completely, validates the internal structure against the RDB format, and optionally verifies the CRC64 checksum at the end of the file, as long as rdbchecksum was active when it was written.

This check surfaces problems that would not be noticed by copying alone, such as a copy corrupted by a faulty storage device or a copy operation interrupted over an unstable network. Backups that fail this check should immediately trigger an alert, instead of silently remaining in the backup inventory as supposedly valid, only for the problem to be revealed months later during an actual restore attempt.

Backup step Without this step With this step
Explicit BGSAVE before copy Backup can be hours old Backup is guaranteed current
redis-check-rdb after copy Corruption goes unnoticed Broken backups caught early
Regular restore test Restore process untested in a real incident Recovery time and process are known
Off-site copy Server failure destroys data and backup Backup survives a total local outage

6. Testing Restores Regularly, Not Just Planning Them

Arguably the most common mistake in backup strategies is testing only the backup itself, never the complete restore process. A backup whose restoration is tried for the first time in a real incident is an uncalculated risk: missing permissions, incorrectly documented paths, or a forgotten configuration step surface exactly when there is no time left to fix them.

A regular, automated restore test, for example monthly on an isolated test instance, uncovers exactly these gaps before they become a problem in a real incident. The test should run through the complete process: fetch the backup file from the archive, load it onto a fresh Redis instance, spot-check data integrity, and log the time needed. This measured recovery time is the only reliable number for a realistic recovery time objective.


#!/usr/bin/env bash
# restore_test.sh - Automated monthly restore drill on an isolated instance
set -euo pipefail

LATEST_BACKUP=$(ls -t /var/backups/redis/dump-*.rdb.gz | head -1)
TEST_DIR="/tmp/redis-restore-test"
START_TIME=$(date +%s)

mkdir -p "$TEST_DIR"
gunzip -c "$LATEST_BACKUP" > "${TEST_DIR}/dump.rdb"

# Validate structure before starting a server against it
redis-check-rdb "${TEST_DIR}/dump.rdb"

# Start an isolated instance on a non-default port for verification
redis-server --port 6390 --dir "$TEST_DIR" --daemonize yes
sleep 2

KEY_COUNT=$(redis-cli -p 6390 DBSIZE)
redis-cli -p 6390 SHUTDOWN NOSAVE

ELAPSED=$(( $(date +%s) - START_TIME ))
echo "[OK] Restore drill complete: ${KEY_COUNT} keys loaded in ${ELAPSED}s"

7. Off-Site Retention: the 3-2-1 Rule for Redis

The classic 3-2-1 backup rule applies unchanged to Redis datasets: at least three copies of the data, on at least two different storage media, with at least one copy physically located at a different site. The production RDB or AOF file counts as the first copy, a local backup on separate storage as the second, and a copy in a different data center or cloud storage bucket as the third, off-site copy.

This third copy protects against scenarios a purely local backup strategy does not cover: a fire or flood in the data center, a complete provider outage, or a compromised root account that wipes both production data and local backups simultaneously. Encrypted uploads to object storage services are well suited for transfer, and the backup file should already be encrypted locally before transfer rather than relying solely on transport encryption.


#!/usr/bin/env bash
# offsite_sync.sh - Encrypt and upload backups off-site
set -euo pipefail

BACKUP_FILE="$1"
ENCRYPTED="${BACKUP_FILE}.enc"

# Encrypt locally before leaving the host (do not rely on transport TLS alone)
openssl enc -aes-256-cbc -pbkdf2 -salt \
  -in "$BACKUP_FILE" -out "$ENCRYPTED" \
  -pass file:/etc/redis/backup.key

# Upload to off-site object storage (example: S3-compatible endpoint)
aws s3 cp "$ENCRYPTED" "s3://redis-backups-offsite/$(basename "$ENCRYPTED")" \
  --storage-class STANDARD_IA

rm -f "$ENCRYPTED"
echo "[OK] Off-site copy uploaded and local encrypted artifact removed"

8. The Actual Restore Process Step by Step

A restore always starts with stopping the target Redis instance, so no conflicting write operations occur during the restoration. Then the saved RDB file, or in the case of AOF the entire appendonlydir directory, is copied into the location configured in redis.conf, and existing, possibly damaged files should be backed up beforehand rather than simply overwritten, in case the restore itself fails.

After copying, the Redis instance is started and the logs are checked for errors during loading, in particular checksum errors or format issues. A final comparison of key count via DBSIZE against a known reference value, along with spot checks of individual critical keys, provides extra confidence that the restore was actually complete and correct, before the instance is released back to production traffic.

Mironsoft

Redis operations, persistence strategy, and backup infrastructure

Backups that actually work in a real incident?

We build automated backup pipelines for your Redis instances, including consistency checks, retention policy, off-site copies, and regular restore tests with documented recovery time.

Backup Automation

Consistent RDB and AOF backups with systemd timers and retention

Restore Drills

Regular, automated recovery tests with reporting

Off-Site Strategy

Set up encrypted off-site copies following the 3-2-1 rule

9. Common Mistakes in Backup Strategies

The most common mistake is creating backups but never testing a restore. That leaves it completely unclear whether the backup process actually works, until exactly the moment it matters. A second common mistake is storing backups on the same physical server or the same storage instance as the production data, which means a single hardware failure destroys both production data and its backup at once.

A third mistake concerns missing alerting for failed backup jobs: a cron job that has been failing for weeks without anyone being notified is functionally equivalent to having no backup at all, with the only difference being a false sense of security. Every backup job should report its exit code and log output to a monitoring system that actively alerts on failures, instead of relying on occasional manual checks.

10. Summary

A robust backup strategy for Redis differs fundamentally from plain RDB or AOF persistence: it forces fresh, consistent snapshots before every copy, automates execution with a clear retention policy, checks every backup with redis-check-rdb for structural integrity, and regularly tests the complete restore process on an isolated instance. Without these elements, a backup remains an unproven assumption rather than a reliable safeguard.

The 3-2-1 rule with at least one encrypted off-site copy additionally protects against scenarios a purely local backup does not cover, from hardware failures to compromised credentials. Combining these elements consistently turns backups from a theoretical checkbox into a genuinely functioning safety mechanism for a real incident.

Backup and Restore Strategies for Redis: the Essentials at a Glance

Consistent Copy

Force an explicit BGSAVE or BGREWRITEAOF before every backup instead of waiting on save points.

Automation

Systemd timers with a clear retention policy, alerting on every failed job.

Restore Tests

Monthly, automated recovery on an isolated instance with documented recovery time.

3-2-1 Rule

Three copies, two media, one encrypted off-site copy outside the production infrastructure.

11. FAQ: Backup and Restore Strategies for Redis

1Is RDB persistence enough as a backup strategy?
No, persistence protects against a process restart, not hardware failures or human errors.
2Why an explicit BGSAVE before backup?
Guarantees a current state instead of a potentially hours-old automatic snapshot.
3What differs in AOF backups?
The whole appendonlydir directory with manifest must be backed up, not just individual files.
4How often to test a restore?
At least monthly, automated on an isolated test instance.
5What does redis-check-rdb do?
Checks an RDB file for structural consistency and checksums without starting a full server.
6What does the 3-2-1 rule mean?
Three copies, two media, one physically located at a different site.
7Should backups be encrypted?
Yes, especially before uploading to external object storage, in addition to transport encryption.
8How long to keep backups?
Two weeks daily, three months weekly, one year monthly is a proven schedule.
9What to do when a backup job fails?
Report exit code and log to a monitoring system that actively alerts on failures.
10Pull backups from a replica?
Yes, recommended, to avoid burdening the primary instance with the backup process.