Intro
Running Redis in production is not just about starting the server. It means verifying the exact version, understanding how your deployment is wired, changing configuration deliberately, and knowing how to prove a change worked or roll it back when it does not. This article is a working checklist for developers, DevOps engineers, and technical startup teams who operate Redis themselves.
Every item is tied to the same loop: observe the current state with read-only commands, define the expected result before you act, make the smallest change that fixes the identified problem, verify the outcome, and keep a tested recovery path. Examples use explicit placeholders like <host> and <port> so you can adapt them without exposing real credentials or private keys.
The focus is on Redis operations, configuration, verification, and recovery. Adjacent topics such as Node.js, Docker, and monitoring appear only when they change prerequisites, observability, or the blast radius of a change.
Version and Environment Inventory
Before touching any Redis setting, know what you are running. Version differences change command syntax, persistence defaults, memory limits, and security behavior. A checklist that does not start here can recommend a command that does not exist in your Redis version.
Start by capturing the installed version and build details:
redis-server --version
redis-cli --version
Expected output resembles:
Redis server v=7.2.4 sha=00000000:0 malloc=jemalloc-5.3.0 bits=64 build=...
redis-cli 7.2.4
If you connect to a remote server, use the documented endpoint and port, never real passwords in examples:
redis-cli -h <host> -p <port> ping
A healthy server responds PONG. A timeout or NOAUTH error tells you authentication is required or the endpoint is wrong.
Next, capture the server topology and role:
redis-cli -h <host> -p <port> info replication
Look for role:master or role:slave. In a Redis Sentinel or Cluster setup, also run:
redis-cli -h <host> -p <port> sentinel get-master-addr-by-name mymaster
redis-cli -h <host> -p <port> cluster nodes
The first command returns the current master IP and port for the sentinel-monitored group named mymaster. The second lists cluster nodes with their IDs, roles, and connection state. Record these values and a UTC timestamp before any change.
Prerequisites for this stage:
- Redis CLI installed locally or on a bastion host with network access to the target.
- Read-only credentials for
INFOandPINGcommands. If ACLs are enabled, use a user with+ping +infoand no write permissions. - Confirmed Redis version to select version-appropriate syntax. For example,
CONFIG GEThas existed for years, butINFOsections changed between 6.x and 7.x.
Blast radius: all commands here are read-only. No state changes.
Verification: you know the exact version, host, port, role, and cluster layout. This is your baseline.
Recovery: no recovery needed for read-only commands. If a command fails, check network, ACL permissions, and Redis logs before proceeding.
Safe Configuration Path
Configuration changes cause more incidents than feature code in many systems. Redis is no exception: a bad maxmemory setting can evict keys aggressively, a wrong save directive can lose durability, and an open protected-mode no without authentication exposes data.
The safe path has five steps:
- Capture current setting.
- Understand the default and your goal.
- Change one scoped parameter.
- Verify the new value and its effect.
- Document the rollback.
Start by reading the current configuration:
redis-cli -h <host> -p <port> CONFIG GET maxmemory
redis-cli -h <host> -p <port> CONFIG GET maxmemory-policy
redis-cli -h <host> -p <port> CONFIG GET save
redis-cli -h <host> -p <port> CONFIG GET appendonly
Example output:
1) "maxmemory"
2) "0"
1) "maxmemory-policy"
2) "noeviction"
1) "save"
2) "3600 1 300 100 60 10000"
1) "appendonly"
2) "no"
This shows unlimited memory, no eviction, RDB snapshots with the given frequency, and AOF disabled. That is a common default, but not always production-ready.
Suppose you want to cap memory at 4 GB and use allkeys-lru to evict less recently used keys when the limit is hit:
redis-cli -h <host> -p <port> CONFIG SET maxmemory 4gb
redis-cli -h <host> -p <port> CONFIG SET maxmemory-policy allkeys-lru
Both return OK.
Verify immediately:
redis-cli -h <host> -p <port> CONFIG GET maxmemory maxmemory-policy
Expected:
1) "maxmemory"
2) "4294967296"
3) "maxmemory-policy"
4) "allkeys-lru"
Check that the change is active by generating memory pressure or using INFO memory, but observe only; do not disrupt production keys.
Prerequisites:
- Redis 4.0 or later for
allkeys-lruwith LFU improvements in later versions. Confirm your version supports the policy. - Permission to run
CONFIG SET(ACL category@adminor explicit+config|set). - Knowledge of how much physical RAM the server has. Never set
maxmemoryabove available RAM minus headroom for replication buffers and fork overhead.
Blast radius: maxmemory affects all keys in the selected database. Eviction can remove keys applications still need. maxmemory-policy changes which keys get evicted. If you set maxmemory lower than current memory usage, Redis starts evicting immediately.
Recovery: to roll back, set the old values:
redis-cli -h <host> -p <port> CONFIG SET maxmemory 0
redis-cli -h <host> -p <port> CONFIG SET maxmemory-policy noeviction
For changes in the redis.conf file, edit the file, then restart or use CONFIG REWRITE if you want persistence without restart. Verify with CONFIG GET after restart.
Always capture the previous values in your runbook before changing. If the change involves security settings like requirepass or rename-command, test in a staging environment first.
Verification and Diagnostics
After any change, verify that the system behaves as intended. Verification is not just checking the config value; it is proving the operational effect.
Use a layered approach:
- Configuration confirmation:
CONFIG GETshows the active value. - Runtime behavior: perform a safe, minimal operation that exercises the changed behavior.
- Performance and health checks: ensure no unexpected load or errors.
For example, after enabling AOF with appendonly yes:
redis-cli -h <host> -p <port> CONFIG SET appendonly yes
redis-cli -h <host> -p <port> CONFIG GET appendonly
The second command should return yes. Then verify persistence is actually working:
redis-cli -h <host> -p <port> BGREWRITEAOF
BGREWRITEAOF returns immediately after starting background rewrite. Check the server log or INFO persistence for aof_rewrite_in_progress:0 and aof_last_rewrite_time_sec within usual range.
Diagnostics for common issues:
- High latency: run
redis-cli --latency -h <host> -p <port>and observe for 30 seconds. Baseline latency and compare after changes. - Memory fragmentation:
INFO memoryfieldsused_memoryandused_memory_rss. If RSS is much higher than used memory with fragmentation ratio > 1.5, consideractivedefrag yes(Redis 4.0+). - Replication lag: on a replica,
INFO replicationshowsmaster_link_status:upandmaster_last_io_seconds_ago. If the value grows continuously, investigate network or disk I/O.
Diagnostic commands are read-only or low-impact. Avoid DEBUG commands or MONITOR in production except under controlled, short sessions because they can degrade performance.
Define expected signals in advance. For example, after changing timeout to 300 seconds to close idle connections, verify with CONFIG GET timeout, then test by opening a connection and waiting; it should be closed by the server after the timeout.
Prerequisites:
- Access to Redis logs and metrics dashboard.
- Understanding of normal baseline for your workload.
- Permission to run diagnostic commands without impacting production traffic.
Blast radius: diagnostic commands are generally safe but can add CPU load. MONITOR and KEYS can block or slow the server; avoid them.
Recovery: if verification shows an unexpected state, revert the change using the recovery steps from the previous section and investigate the cause before re-applying.
Failure Modes and Recovery
Redis fails in predictable ways. Preparing for failure means identifying the most likely modes and practicing recovery.
Common failure modes
- Out of memory:
maxmemoryexceeded and policy isnoeviction. Writes fail withOOM command not allowed when used memory > 'maxmemory'. Applications receive errors.
- Persistence failure: disk full or I/O error during RDB save or AOF append. Redis may continue serving reads but durability is compromised.
- Replication down: network partition between master and replica. Replica retries, but lag grows.
- Master crash: all writes fail until failover. In Sentinel, automatic failover occurs; in standalone, manual intervention needed.
- Data corruption: AOF or RDB file corrupted, causing startup failure.
- Connection storm: too many clients due to misconfigured client library or a bug, exhausting file descriptors.
Recovery procedures
For each, have a tested procedure. Example for out of memory:
redis-cli -h <host> -p <port> INFO memory
Look at used_memory, maxmemory, maxmemory_policy. If used memory is at max, decide: increase maxmemory safely, change policy to allow eviction, or reduce data size by deleting expired or less critical keys using SCAN + DEL in batches.
Example batch eviction of keys with a pattern, without blocking:
redis-cli -h <host> -p <port> --scan --pattern 'temp:*' | while read key; do redis-cli -h <host> -p <port> DEL "$key"; done
But use with care and after identifying keys. Prefer UNLINK over DEL for large keys to avoid blocking.
For persistence failure, check disk space and Redis log. If disk is full, free space or redirect dir to a larger volume. If AOF is corrupted, use redis-check-aof --fix <filename> after stopping Redis, but be aware it may truncate the file and lose recent writes.
For replication failure, verify network connectivity and firewall rules. Check INFO replication on both sides. If the replica is too far behind, it may do a full resynchronization, which loads the master. Do this during low traffic if possible.
For master crash with no failover, restore from the latest RDB/AOF and start a new master. If using Sentinel, ensure quorum is met and failover triggers automatically; test this regularly.
Prerequisites:
- Backups that are tested and recent.
- Monitoring alerts on memory, disk, replication, and client connections.
- Runbooks for each failure mode.
Blast radius: recovery actions often affect all data. Practice in a staging environment.
Verification: after recovery, run health checks: PING, INFO memory/persistence/replication, and application smoke tests.
Operations Checklist
Use this summary as a repeatable checklist. Each item has an owner and a review frequency.
Daily checks (owner: on-call engineer, reviewed continuously via monitoring)
- Run
redis-cli -h <host> -p <port> pingto confirm server is responsive. - Check memory usage:
INFO memoryand compare with maxmemory. - Monitor client connections:
INFO clientsand look for blocked clients. - Verify replication status:
INFO replicationand ensuremaster_link_status:up. - Check log files for errors or warnings.
Weekly checks (owner: DevOps engineer, reviewed every Monday)
- Inspect Redis slow log:
SLOWLOG GET 25and optimize slow commands. - Review key evictions:
INFO statsfieldsevicted_keysandexpired_keys. - Check persistence:
INFO persistenceand verify latest RDB/AOF creation timestamps and sizes. - Validate backup integrity by restoring a random backup to a test instance.
Monthly checks (owner: team lead or Redis administrator, reviewed monthly)
- Review configuration against a baseline template and document changes.
- Re-assess memory limits and policies based on usage trends.
- Test failover: in a staging environment, stop the master and ensure Sentinel or manual failover works.
- Update runbooks and contact lists.
Quarterly checks (owner: engineering manager, reviewed quarterly)
- Review access controls and ACLs; rotate passwords if used.
- Plan capacity: project memory and storage growth; upgrade if needed.
- Conduct a full disaster recovery drill.
Example checklist with concrete values
| Check | Command | Expected Result | Failure Signal | Owner | Frequency |
|---|---|---|---|---|---|
| Server alive | redis-cli -h 10.0.0.5 -p 6379 ping | PONG | Timeout or error | Priya Shah, On-call | Daily |
| Memory usage | redis-cli -h 10.0.0.5 -p 6379 INFO memory | used_memory_human below 80% of maxmemory_human | Used > 90% | Priya Shah, On-call | Daily |
| Replication lag | redis-cli -h 10.0.0.6 -p 6379 INFO replication | master_last_io_seconds_ago < 10 | > 60 seconds | Carlos Mendes, DevOps | Weekly |
| Slow commands | SLOWLOG GET 10 | No severe slow entries or all < 50ms | Commands > 500ms repeated | Carlos Mendes, DevOps | Weekly |
| Backup test | Restore latest RDB to staging | Keys restored, app smoke test passes | Restore fails or missing data | Aiko Tanaka, DB Admin | Weekly |
| Failover drill | Simulated master stop in staging | Sentinel promotes replica within 60s | No promotion or split-brain | Raj Patel, Eng Manager | Monthly |
| ACL review | ACL LIST and compare with inventory | All users have minimal required permissions | Unknown user or over-permission | Aiko Tanaka, DB Admin | Quarterly |
Replace IPs, port, and names with your own. Never put real passwords in these commands; use environment variables or prompt for secrets.
Common Pitfalls and How to Avoid Them
1. Running Redis with default configuration in production
Why it happens: quick setup in development carries over to production. How to avoid: create a hardened redis.conf with protected-mode yes, bind to internal interfaces, set requirepass or use ACL, and set maxmemory. How to recover: audit with CONFIG GET * and fix settings; restart with corrected config or use CONFIG SET and CONFIG REWRITE.
2. Using KEYS command in production
Why it happens: developers use KEYS pattern for debugging, not realizing it blocks the server for all other commands. How to avoid: use SCAN with a cursor, which iterates incrementally. Enforce with ACL: disallow KEYS for application users. How to recover: if KEYS is running and causing latency, wait for it to finish or, in extreme cases, restart Redis (last resort). Then replace all KEYS usage with SCAN in code.
3. Ignoring persistence trade-offs
Why it happens: assuming Redis is just a cache and durability is not needed, then losing data on restart surprises the team. How to avoid: explicitly choose RDB, AOF, or both based on recovery point objective. For most production, enable AOF with appendfsync everysec and periodic RDB snapshots. How to recover: enable AOF and create a fresh snapshot; test recovery.
4. Not setting maxmemory
Why it happens: default maxmemory 0 means no limit, and the OS may kill Redis when memory runs out. How to avoid: set maxmemory to about 70-80% of available RAM, and choose an eviction policy appropriate for your data. How to recover: set maxmemory and policy, monitor evictions.
5. Renaming critical commands without updating clients
Why it happens: security hardening renames CONFIG, FLUSHALL, etc., but clients that legitimately use them break. How to avoid: audit client usage before renaming; use ACLs to restrict instead of renaming for whole server when possible. How to recover: revert rename or update client code and restart.
6. Not testing failover
Why it happens: failover is complex and assumed to work because it is configured. How to avoid: schedule regular failover drills in staging and occasionally in production if safe. How to recover: after a real failover, review logs and monitoring to ensure promotion and data consistency.
Each pitfall can be prevented with good defaults, monitoring, and regular review. When a mistake happens, the recovery should be a known set of steps, not an ad-hoc response.
Conclusion
A Redis production operations checklist is only as good as your willingness to use it before and after every change. The core discipline is observation before intervention: capture version and topology, read current configuration, make one scoped change with a defined expected result, verify with commands and metrics, and keep a rollback path.
The examples in this article show the exact commands for inventory, configuration, diagnostics, and recovery. Replace placeholders with your hosts and ports, but never with real credentials in a shared document.
Start small: choose one low-risk verification from the checklist, record the current state, run the check, compare against the expected signal, and then expand. Review dependencies such as Node.js clients, Docker networking, or monitoring integrations only where they affect Redis behavior. Make failure visible, protect sensitive values, limit changes to the intended resource, and test recovery before an incident forces the decision. A well-operated Redis is not magic; it is a set of habits, repeated until they become second nature.