Install and Tune Redis for Production
Install Redis on Linux, configure RDB and AOF persistence, set maxmemory eviction policies, and add replication with Sentinel for production HA.
Before you start
- ▸Root or sudo access on all nodes
- ▸Redis 7.x (some directives differ on Redis 6.x)
- ▸For replication and Sentinel: at least two Redis hosts and three Sentinel hosts with private network connectivity
- ▸Firewall rules allowing port 6379 (Redis) and 26379 (Sentinel) between cluster nodes only
Redis is deceptively easy to install and dangerously easy to misconfigure. A default install listens on every interface, has no password, no memory ceiling, and loses data on crash. This guide closes those gaps: you will install Redis, lock it down, choose a persistence strategy, set a memory policy, and optionally add replication with Sentinel for high availability.
Installation
Debian / Ubuntu
The OS repositories often ship an older Redis. Use the official Redis repository for the current stable release.
curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" \
| sudo tee /etc/apt/sources.list.d/redis.list
sudo apt update && sudo apt install -y redis
Fedora / RHEL 9 / Rocky 9
sudo dnf install -y redis
sudo systemctl enable --now redis
Arch Linux
sudo pacman -S redis
sudo systemctl enable --now redis
Confirm the version you have before tuning — some options (e.g., latency-tracking) require Redis 7+.
redis-cli ping
redis-cli info server | grep redis_version
Lock Down the Basics
The main configuration file is /etc/redis/redis.conf on Debian/Ubuntu and /etc/redis.conf on Fedora/RHEL/Arch. All edits below apply to whichever path exists on your system.
Bind to localhost only
Unless Redis is your replication primary serving remote replicas, restrict it to loopback. For replication, bind to the specific private interface instead.
sudo sed -i 's/^bind .*/bind 127.0.0.1 -::1/' /etc/redis/redis.conf
Require a strong password
redis-cli acl genpass 64
Copy the output, then set it in the config:
sudo sed -i 's/^# requirepass .*/requirepass YOUR_GENERATED_PASSWORD/' /etc/redis/redis.conf
Disable the default user if using ACLs (Redis 6+)
# Add to redis.conf
aclfile /etc/redis/users.acl
Manage users with redis-cli acl setuser rather than editing the file by hand in production.
Persistence: RDB vs AOF
Redis offers two persistence mechanisms. They are not mutually exclusive — running both is the recommended production baseline.
RDB (snapshotting)
RDB writes a point-in-time binary snapshot. It is compact and fast to restore but you can lose up to the last snapshot interval of writes on a crash.
# redis.conf — save every 900s if ≥1 key changed, etc.
save 900 1
save 300 10
save 60 10000
dbfilename dump.rdb
dir /var/lib/redis
rdbcompression yes
For a cache-only node where losing data is acceptable, disable RDB entirely:
save ""
AOF (Append-Only File)
AOF logs every write command. Combined with fsync policy it can limit data loss to at most one second — or zero, at a throughput cost.
appendonly yes
appendfilename "appendonly.aof"
# everysec: fsync once per second — good balance for most workloads
# always: fsync on every write — safest, slowest
# no: let the OS decide — fastest, most data risk
appendfsync everysec
# Prevent AOF rewrites from blocking during heavy I/O
no-appendfsync-on-rewrite yes
# Trigger rewrite when AOF grows 100% beyond last rewrite size
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
Running both (recommended)
Enable both RDB and AOF. On restart Redis will prefer the AOF file because it is more complete. RDB remains useful as an offline backup and for faster replica syncs.
Memory Management
Set a hard memory ceiling
Without maxmemory, Redis will consume all available RAM and trigger OOM-killer. Set it to roughly 75 % of the RAM you want to dedicate to Redis.
maxmemory 2gb
Choose an eviction policy
When maxmemory is reached Redis must decide what to do. Pick the policy that matches your use case.
| Policy | Evicts | Best for |
|---|---|---|
| noeviction | Nothing — errors on writes | Primary datastores where data loss is unacceptable |
| allkeys-lru | Least-recently-used across all keys | General-purpose caches |
| volatile-lru | LRU among keys with a TTL set | Mixed persistent + cached data |
| allkeys-lfu | Least-frequently-used across all keys | Skewed access patterns |
| volatile-ttl | Keys closest to expiry first | Session stores |
maxmemory-policy allkeys-lru
Additional memory tweaks
# Use less memory for small hashes/lists/sets
hash-max-listpack-entries 128
hash-max-listpack-value 64
# Disable Transparent Huge Pages at the OS level (not a Redis setting)
# Add to /etc/rc.local or a systemd drop-in:
# echo never > /sys/kernel/mm/transparent_hugepage/enabled
Replication
Redis replication is asynchronous and single-leader. One node is the primary; one or more replicas stream changes from it.
Configure the replica
On each replica node, add to redis.conf:
replicaof 192.168.1.10 6379
masterauth YOUR_GENERATED_PASSWORD
replica-read-only yes
# Serve potentially stale data rather than erroring when replica lags
replica-serve-stale-data yes
Verify replication
# On the primary:
redis-cli -a YOUR_GENERATED_PASSWORD info replication
Look for role:master and at least one slave0: entry showing state=online. Output will vary by setup.
High Availability with Sentinel
Sentinel monitors your Redis topology and promotes a replica automatically if the primary fails. You need at least three Sentinel processes (on separate hosts or VMs) to form a reliable quorum.
Sentinel configuration
Create /etc/redis/sentinel.conf on each Sentinel host:
port 26379
daemonize no
# Monitor primary, quorum = 2 (majority of 3 sentinels)
sentinel monitor mymaster 192.168.1.10 6379 2
sentinel auth-pass mymaster YOUR_GENERATED_PASSWORD
# Declare primary down after 5 seconds of no response
sentinel down-after-milliseconds mymaster 5000
# Allow only 1 replica to sync from the new primary at a time during failover
sentinel parallel-syncs mymaster 1
# Abort a failover if it takes longer than 3 minutes
sentinel failover-timeout mymaster 180000
logfile /var/log/redis/sentinel.log
Run Sentinel as a systemd service
sudo tee /etc/systemd/system/redis-sentinel.service <<'EOF'
[Unit]
Description=Redis Sentinel
After=network.target
[Service]
Type=notify
ExecStart=/usr/bin/redis-sentinel /etc/redis/sentinel.conf --supervised systemd
Restart=on-failure
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now redis-sentinel
Check Sentinel status
redis-cli -p 26379 sentinel masters
Verification Checklist
# 1. Service is running and enabled
systemctl is-active redis && systemctl is-enabled redis
# 2. Only loopback is listening (no 0.0.0.0)
ss -tlnp | grep 6379
# 3. Authentication is enforced
redis-cli ping # should return NOAUTH error without -a flag
# 4. Persistence files exist
ls -lh /var/lib/redis/
# 5. Memory policy is set
redis-cli -a YOUR_GENERATED_PASSWORD config get maxmemory-policy
Troubleshooting
Redis won't start after config changes
Check for syntax errors before restarting:
redis-server /etc/redis/redis.conf --test-memory 256
redis-server /etc/redis/redis.conf --loglevel verbose &
Errors are printed to stderr immediately. The most common culprits are a mis-formatted save directive or a bad bind address.
High memory usage / unexpected evictions
redis-cli -a YOUR_GENERATED_PASSWORD info memory
redis-cli -a YOUR_GENERATED_PASSWORD info stats | grep evicted_keys
If evicted_keys is growing rapidly your maxmemory ceiling is too low or your TTL strategy needs review.
Replication lag
redis-cli -a YOUR_GENERATED_PASSWORD info replication | grep lag
Persistent lag usually means network saturation or a slow disk on the replica. Reduce auto-aof-rewrite-min-size or move the AOF to a faster disk.
THP causing latency spikes
Redis logs a warning if Transparent Huge Pages are enabled. Disable them persistently via a systemd service unit rather than /etc/rc.local, which is fragile on modern systems.
sudo tee /etc/systemd/system/disable-thp.service <<'EOF'
[Unit]
Description=Disable Transparent Huge Pages
DefaultDependencies=no
After=sysinit.target local-fs.target
Before=redis.service
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'echo never > /sys/kernel/mm/transparent_hugepage/enabled'
RemainAfterExit=yes
[Install]
WantedBy=basic.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now disable-thpFrequently asked questions
- Should I use RDB, AOF, or both in production?
- Use both. AOF with appendfsync everysec limits data loss to roughly one second, while RDB snapshots give you compact backups and speed up initial replica syncs. Redis will prefer the AOF on restart when both are present.
- What maxmemory-policy should I pick for a session store?
- Use volatile-ttl if all session keys have a TTL set, so Redis evicts the soonest-to-expire sessions first. If some keys lack TTLs, volatile-lru is a safer fallback.
- How many Sentinel instances do I need?
- A minimum of three, each on a separate host or VM, with a quorum of 2. Fewer than three means a single Sentinel failure can prevent a quorum from forming, defeating the purpose of HA.
- Does Redis replication guarantee no data loss on failover?
- No. Replication is asynchronous by default, so writes acknowledged by the primary but not yet streamed to a replica can be lost during an unclean failover. Use min-replicas-to-write and min-replicas-max-lag to reduce the window.
- Can I reload redis.conf changes without a full restart?
- Most runtime parameters can be applied with 'redis-cli config set' without a restart. A small set of directives — including bind, daemonize, and port — require a full service restart to take effect.
Related guides
Configure Prometheus Alertmanager
Configure Prometheus Alertmanager with routing trees, receivers, inhibition rules, grouping, Go templates, and PagerDuty/Slack on-call integrations.
Build an Intranet Server on Linux
Set up a complete small-office intranet on one Linux box: Nginx web server, dnsmasq local DNS, Samba file sharing, and a Wiki.js team wiki.
Build an nftables Firewall Script
Build a complete nftables firewall from scratch: tables, chains, sets, default-deny input policy, service allowlisting, and persistent systemd configuration.
Caddy as a Reverse Proxy
Set up Caddy as a reverse proxy with automatic HTTPS, load balancing, WebSocket passthrough, reusable snippets, and header control — no certbot required.