The Error
You trigger a manual snapshot and Redis shoots back:
127.0.0.1:6379> BGSAVE
(error) ERR Background save already in progress
A BGSAVE fork is already running โ Redis won't let you stack two. Most of the time this is harmless. But at 2 AM with a deployment waiting, you need to know what's happening and when it'll be done.
Why This Happens
Redis handles RDB snapshots by forking a child process. Only one fork runs at a time. The error fires when:
- A previous
BGSAVEโ manual or triggered bysaveconfig rules โ hasn't finished yet - A
BGREWRITEAOFis running โ on older Redis versions, AOF rewrites also blockBGSAVE - A replica just connected and Redis forked to send it an RDB (replication-triggered implicit save)
Nothing is broken. Redis is protecting you from double-forking. Your job is to either wait for the current save to finish, or figure out why saves are taking too long in the first place.
Step 1 โ Check What's Actually Running
Start here โ pull the current persistence state:
redis-cli INFO persistence
The fields that matter:
rdb_bgsave_in_progress:1 # 1 = a save is running right now
rdb_current_bgsave_time_sec:42 # seconds elapsed since the save started
rdb_last_bgsave_status:ok # status of the last completed save
aof_rewrite_in_progress:0 # 1 = AOF rewrite is forked
rdb_bgsave_in_progress:1 means a save is active. Wait. Redis sets it back to 0 when done.
Step 2 โ Wait It Out (the Right Way)
Poll until the save finishes:
watch -n 2 'redis-cli INFO persistence | grep -E "bgsave_in_progress|bgsave_time_sec|last_bgsave"'
On a dataset under a few GB with normal disk I/O, BGSAVE wraps up in seconds to a couple of minutes. Past the 5โ10 minute mark, something's wrong โ skip to the troubleshooting section below.
Once rdb_bgsave_in_progress drops to 0, re-run your BGSAVE:
127.0.0.1:6379> BGSAVE
Background saving started
Step 3 โ Find What Triggered the Original Save
The Redis log tells you exactly what kicked it off:
tail -n 100 /var/log/redis/redis-server.log | grep -i "bgsave\|save\|fork"
Common log lines:
# Manual BGSAVE
* Background saving started by pid 12345
# Triggered by save rules (e.g. save 300 10)
* 10000 changes in 300 seconds. Saving...
# Triggered by replication
* Starting BGSAVE for SYNC with target: disk
A replication-triggered save? Check your replica connections:
redis-cli INFO replication | grep -E "connected_slaves|slave"
Step 4 โ If BGSAVE Is Taking Too Long
Slow saves come down to three causes. Work through them in order.
High memory dataset with slow disk
The child process writes your entire dataset to disk โ every byte. On a 10 GB dataset with a spinning disk doing 100 MB/s, that's at least 100 seconds before you even account for overhead. Check your dataset size and disk throughput:
redis-cli INFO memory | grep used_memory_human
iostat -x 1 5 # check disk utilization
Maxed-out disk I/O means the save will crawl. Move your RDB file to a faster volume:
# redis.conf
dir /mnt/fast-ssd/redis
Copy-on-write pressure from high write load
After fork, every write to Redis causes the OS to copy affected memory pages (copy-on-write). High write throughput during a save balloons the child's working set. The more pages get copied, the longer the save takes. Check how much has changed since the last save:
redis-cli INFO stats | grep rdb_changes_since_last_save
A large number here means your save interval is too wide. Tighten it or schedule saves during off-peak hours.
Transparent Huge Pages causing fork latency
THP is a well-known Redis performance killer โ it inflates copy-on-write overhead significantly. Check and disable it:
cat /sys/kernel/mm/transparent_hugepage/enabled
# If it shows [always], disable it:
echo never > /sys/kernel/mm/transparent_hugepage/enabled
Step 5 โ Tune Save Frequency to Avoid Conflicts
Frequent auto-saves are the usual culprit on busy servers. The default rules fire aggressively โ on a large dataset, saves can overlap. Dial them back in redis.conf:
# Default (often too aggressive for large datasets)
save 900 1
save 300 10
save 60 10000
# More conservative โ only save on significant change volume
save 900 1
save 300 1000
Apply without restart:
redis-cli CONFIG SET save "900 1 300 1000"
To confirm the live config took effect:
redis-cli CONFIG GET save
Verification
Confirm the save completed cleanly:
redis-cli INFO persistence | grep -E "rdb_bgsave_in_progress|rdb_last_bgsave_status|rdb_last_save_time"
Healthy output looks like this:
rdb_bgsave_in_progress:0
rdb_last_bgsave_status:ok
rdb_last_save_time:1714900000
Then check the RDB file itself was updated:
ls -lh $(redis-cli CONFIG GET dir | tail -1)/$(redis-cli CONFIG GET dbfilename | tail -1)
The timestamp should match your recent save.
Quick Reference
- Safe to ignore if a save is already in progress โ just wait for it to finish
- Check status:
redis-cli INFO persistence | grep bgsave - Never kill the BGSAVE child manually unless it's been running for hours โ killing mid-write corrupts the RDB file
- LASTSAVE returns a Unix timestamp of the last successful save:
redis-cli LASTSAVE - To stop all saves entirely:
redis-cli CONFIG SET save ""โ only do this if you understand what persistence you're giving up

