Key Takeaways
bind 127.0.0.1is mandatory: Redis has no auth by default. Never expose port 6379 to the internet without authentication and firewall protection.- ACL over requirepass: Use
ACL SETUSER appuser on >strongpassword ~app:* +get +set +delto create application-specific users — more granular than a single shared password. - AOF for durability:
appendonly yeswithappendfsync everysecloses at most 1 second of data on crash — far better than RDB-only which can lose minutes. - maxmemory + eviction policy: Always set
maxmemoryto prevent Redis consuming all available RAM, andmaxmemory-policy allkeys-lruto evict the least-recently-used keys when full.
Introduction
Direct Answer: How do I install and secure Redis on Ubuntu 24.04 LTS in 2026?
Install Redis with sudo apt-get install -y redis-server. Immediately secure it: open /etc/redis/redis.conf, change bind 0.0.0.0 to bind 127.0.0.1 ::1, set requirepass YourStrongPassword, set maxmemory 256mb and maxmemory-policy allkeys-lru. Restart with sudo systemctl restart redis-server. Test with redis-cli -a YourStrongPassword ping — should return PONG. Enable AOF persistence: appendonly yes and appendfsync everysec. Check status with redis-cli -a YourStrongPassword info server. For application connections, use redis://default:[email protected]:6379 as the connection string. Redis 7.4 ships with Ubuntu 24.04’s package repositories — no additional PPA needed.
Part 1: Installation
sudo apt-get update
sudo apt-get install -y redis-server
# Verify
redis-server --version
sudo systemctl status redis-server --no-pager | grep "Active:"
Expected output:
Redis server v=7.4.0 sha=00000000:0 malloc=jemalloc-5.3.0 bits=64
Active: active (running)
# Test connectivity (unauthenticated — fix this next)
redis-cli ping
Expected output:
PONG
Part 2: Security Configuration
# Edit Redis configuration
sudo cp /etc/redis/redis.conf /etc/redis/redis.conf.backup
sudo tee /etc/redis/redis.conf << 'EOF'
# ── Binding & Networking ──────────────────────────────────────────────────
# NEVER bind to 0.0.0.0 in production — restricts to localhost only
bind 127.0.0.1 ::1
port 6379
protected-mode yes
# ── Authentication ────────────────────────────────────────────────────────
# requirepass is the simple approach; see ACL section for multi-user
requirepass change_this_to_a_strong_password_32chars
# ── Memory Management ─────────────────────────────────────────────────────
maxmemory 256mb
# Eviction policy when maxmemory reached:
# allkeys-lru: evict least-recently-used keys (best for caches)
# volatile-lru: only evict keys with TTL set (best for mixed workloads)
maxmemory-policy allkeys-lru
# ── Persistence ───────────────────────────────────────────────────────────
# RDB snapshots
save 3600 1 # Save if 1+ keys changed in 1 hour
save 300 100 # Save if 100+ keys changed in 5 minutes
save 60 10000 # Save if 10000+ keys changed in 1 minute
# AOF (Append Only File) — more durable
appendonly yes
appendfsync everysec # Sync to disk every second (max 1s of data loss)
no-appendfsync-on-rewrite no
# ── Logging ───────────────────────────────────────────────────────────────
loglevel notice
logfile /var/log/redis/redis-server.log
# ── Security Hardening ────────────────────────────────────────────────────
# Rename dangerous commands (empty string = disable)
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command CONFIG ""
rename-command DEBUG ""
rename-command SHUTDOWN SHUTDOWN_9a2f8b3c # Only you know the rename
rename-command SLAVEOF ""
# ── Performance ───────────────────────────────────────────────────────────
tcp-keepalive 300
timeout 0
databases 16
EOF
sudo systemctl restart redis-server
sudo systemctl status redis-server --no-pager | grep "Active:"
Expected output:
Active: active (running)
# Test with authentication
redis-cli -a "change_this_to_a_strong_password_32chars" ping
redis-cli -a "change_this_to_a_strong_password_32chars" info server | grep -E "redis_version|uptime|connected"
Expected output:
PONG
redis_version:7.4.0
uptime_in_seconds:15
connected_clients:1
Part 3: ACL Users (Modern Multi-App Setup)
# Create application-specific users with limited permissions
redis-cli -a "change_this_to_a_strong_password_32chars" << 'REDIS'
# Create a user for the web app — can read/write app:* keys only
ACL SETUSER webapp on >webapp_strong_password ~app:* +get +set +del +expire +ttl +exists
# Create a read-only user for analytics
ACL SETUSER analytics on >analytics_password ~app:* +get +keys +scan +type
# Create admin user (rename from default)
ACL SETUSER admin on >admin_password ~* &* +@all
# Disable the default user
ACL SETUSER default off
# Verify
ACL LIST
REDIS
Expected output:
OK
OK
OK
OK
user webapp on #[password_hash] ~app:* &* +get +set +del +expire +ttl +exists
user analytics on #[password_hash] ~app:* &* +get +keys +scan +type
user admin on #[password_hash] ~* &* +@all
user default off nopass ~* &* +@all
# Test webapp user — can only access app:* keys
redis-cli --user webapp --pass webapp_strong_password set app:session:123 '{"user_id": 456}' EX 3600
redis-cli --user webapp --pass webapp_strong_password get app:session:123
# Test restriction — webapp user cannot access other keys
redis-cli --user webapp --pass webapp_strong_password set other:key value 2>&1 | head -1
Expected output:
OK
{"user_id": 456}
(error) NOPERM this user has no permissions to access one of the keys used as arguments
Part 4: Common Redis Operations
# Connect as admin
REDIS="redis-cli --user admin --pass admin_password"
# ── Strings ───────────────────────────────────────────────────────────────
$REDIS SET greeting "Hello, sovereign Redis!"
$REDIS GET greeting
$REDIS SET counter 0
$REDIS INCR counter # Atomic increment
$REDIS INCRBY counter 10
$REDIS GET counter # Returns 11
# ── Keys with TTL (expiry) ────────────────────────────────────────────────
$REDIS SET session:abc123 '{"user_id":1}' EX 3600 # Expires in 1 hour
$REDIS TTL session:abc123 # Check remaining TTL
$REDIS PERSIST session:abc123 # Remove TTL (make permanent)
# ── Hash (structured data) ────────────────────────────────────────────────
$REDIS HSET user:1 name "Divya" email "[email protected]" role "admin"
$REDIS HGET user:1 name
$REDIS HGETALL user:1
# ── List (queue/stack) ────────────────────────────────────────────────────
$REDIS RPUSH tasks "send-email" "process-payment" "update-search"
$REDIS LLEN tasks # Queue length
$REDIS LPOP tasks # Dequeue from left (FIFO)
# ── Set ───────────────────────────────────────────────────────────────────
$REDIS SADD online:users user:1 user:2 user:3
$REDIS SISMEMBER online:users user:1 # Is user online?
$REDIS SCARD online:users # Count online users
# ── Sorted Set (leaderboard) ──────────────────────────────────────────────
$REDIS ZADD leaderboard 1000 "alice" 850 "bob" 920 "charlie"
$REDIS ZRANGE leaderboard 0 -1 WITHSCORES REV # Top scores (highest first)
Expected output (HGETALL user:1):
1) "name"
2) "Divya"
3) "email"
4) "[email protected]"
5) "role"
6) "admin"
Part 5: Redis as a Python Session Store
# session_store.py — using Redis as a web app session backend
import redis
import json
import secrets
from datetime import timedelta
# Connection with ACL user
r = redis.Redis(
host="127.0.0.1",
port=6379,
username="webapp",
password="webapp_strong_password",
decode_responses=True, # Return strings, not bytes
socket_connect_timeout=2,
retry_on_timeout=True,
)
SESSION_TTL = 3600 # 1 hour
def create_session(user_id: int, metadata: dict = {}) -> str:
"""Create a new session and return the session token."""
token = secrets.token_urlsafe(32)
key = f"app:session:{token}"
payload = json.dumps({"user_id": user_id, **metadata})
r.setex(key, SESSION_TTL, payload)
return token
def get_session(token: str) -> dict | None:
"""Get session data and refresh TTL."""
key = f"app:session:{token}"
data = r.get(key)
if not data:
return None
r.expire(key, SESSION_TTL) # Sliding expiry — reset TTL on access
return json.loads(data)
def delete_session(token: str) -> None:
"""Invalidate a session (logout)."""
r.delete(f"app:session:{token}")
# Test
token = create_session(user_id=42, metadata={"role": "admin", "ip": "192.168.1.1"})
print(f"Session token: {token[:16]}...")
session = get_session(token)
print(f"Session data: {session}")
print(f"TTL: {r.ttl(f'app:session:{token}')}s")
delete_session(token)
print(f"After logout: {get_session(token)}")
Expected output:
Session token: vJ8K2mNpQrS4tU6x...
Session data: {'user_id': 42, 'role': 'admin', 'ip': '192.168.1.1'}
TTL: 3599s
After logout: None
Part 6: Backup and Monitoring
# ── Backup ────────────────────────────────────────────────────────────────
# Trigger RDB snapshot
redis-cli --user admin --pass admin_password BGSAVE
sleep 2
ls -lh /var/lib/redis/dump.rdb # RDB backup file
# Backup to a timestamped file
sudo cp /var/lib/redis/dump.rdb \
/var/backups/redis-$(date +%Y%m%d_%H%M).rdb
echo "Backed up"
# ── Monitoring ────────────────────────────────────────────────────────────
redis-cli --user admin --pass admin_password info all | grep -E \
"connected_clients|used_memory_human|keyspace_hits|keyspace_misses|evicted_keys|total_commands"
Expected output:
connected_clients:2
used_memory_human:1.23M
keyspace_hits:1847
keyspace_misses:23
evicted_keys:0
total_commands_processed:2941
# Calculate hit rate
redis-cli --user admin --pass admin_password info stats | python3 -c "
import sys
stats = {}
for line in sys.stdin:
if ':' in line:
k, v = line.strip().split(':', 1)
stats[k] = v
hits = int(stats.get('keyspace_hits', 0))
misses = int(stats.get('keyspace_misses', 0))
total = hits + misses
hit_rate = (hits / total * 100) if total > 0 else 0
print(f'Cache hit rate: {hit_rate:.1f}% ({hits} hits, {misses} misses)')
"
Expected output:
Cache hit rate: 98.8% (1847 hits, 23 misses)
Troubleshooting
NOAUTH Authentication required
Redis requires authentication but none was provided.
Fix: Add -a "password" to redis-cli, or --user username --pass password for ACL users. In Python: redis.Redis(password="pass").
OOM command not allowed when used memory > 'maxmemory'
Redis is full and the eviction policy doesn’t allow new writes.
Fix: Increase maxmemory in redis.conf, or check if maxmemory-policy is set correctly. noeviction returns errors when full — change to allkeys-lru for caching workloads.
Connection refused on port 6379
Redis is bound to 127.0.0.1 only (correct) but you’re connecting from a different host.
Fix: Connect via SSH tunnel: ssh -L 6379:localhost:6379 user@server then redis-cli -p 6379.
Conclusion
Redis is running, secured with ACL users, configured with AOF persistence for durability, and memory-limited to prevent OOM. The Python session store implementation shows the core web application pattern — create, get, and delete sessions with sliding TTL expiry.
See Docker Compose Tutorial 2026 for running Redis alongside your application in a containerised stack, and PostgreSQL vs MySQL 2026 for when a persistent relational database is more appropriate than Redis.
People Also Ask
What is the difference between Redis RDB and AOF persistence?
RDB (Redis Database) creates periodic point-in-time snapshots — fast to restore, smaller files, but can lose minutes of data on crash. AOF (Append Only File) logs every write command — near-zero data loss (at most 1 second with appendfsync everysec), but larger files and slightly slower writes. For production caches: RDB only is acceptable (data is regeneratable). For session stores and queues: use both RDB and AOF — RDB for fast restores, AOF for minimal data loss.
Should Redis be exposed on a public IP?
Never expose Redis directly on a public IP. Redis is designed for trusted internal networks — it has no TLS by default (though Redis 6+ supports it), and even with authentication, a misconfigured Redis has caused numerous data breaches. Always: bind 127.0.0.1, use UFW to block port 6379 from external access, and connect via SSH tunnel or private network if access from another server is needed.
Part 12: Secure Redis Architecture
A secure Redis deployment starts with a clear architecture.
12.1 Network isolation
Keep Redis on a private network. Do not expose it to the public internet unless you have a secure tunnel or proxy in front of it.
12.2 Role-based instances
Use separate Redis instances for caching, session storage, and critical persistent data. This prevents cache churn or a noisy tenant from affecting sensitive workloads.
12.3 Dedicated resources
Give Redis dedicated CPU and memory when possible. Shared hosts can lead to unpredictable latency and resource contention.
Part 13: Access Control with ACLs
Redis ACLs are the best practice for production security.
13.1 Creating user accounts
Create named users for each application or service.
ACL SETUSER app_user on >strongpassword ~app:* +GET +SET +EXPIRE
Avoid the default default user and disable commands that are not needed.
13.2 Restricting commands
Limit each user to the commands required by its workload. For example, a cache-only user does not need FLUSHALL or CONFIG.
13.3 Monitoring ACL usage
Log ACL authentication failures and command rejections. These can surface misconfigured clients or unauthorized access attempts.
Part 14: TLS and Encryption
Encrypt Redis traffic in transit and protect sensitive data at rest.
14.1 TLS setup
Enable TLS with certificate-based authentication if possible.
tls-port 6379
tls-cert-file /etc/redis/redis.crt
tls-key-file /etc/redis/redis.key
14.2 Client-side TLS enforcement
Require clients to connect with TLS and verify the server certificate.
14.3 Encryption at rest
For sensitive data, run Redis on encrypted storage volumes. This protects snapshot files and append-only logs.
Part 15: Persistence and Durability
Redis can be fast and durable if configured carefully.
15.1 RDB snapshots
Use RDB snapshots for periodic persistence and fast restarts. Configure a sensible snapshot schedule.
save 900 1
save 300 10
save 60 10000
15.2 AOF persistence
Enable AOF for write durability.
aof-enabled yes
aof-use-rdb-preamble yes
aof-rewrite-percentage 100
aof-rewrite-min-size 64mb
Use appendfsync everysec for a good durability/performance balance.
15.3 Backup strategy
Back up snapshots and AOF files regularly. Keep off-host copies and test recovery procedures.
Part 16: High Availability and Scaling
A production Redis setup should survive node failures.
16.1 Sentinel for failover
Use Redis Sentinel to monitor masters and perform automated failover.
sentinel monitor mymaster 127.0.0.1 6379 2
Configure notification scripts and failover timeouts that match your SLA requirements.
16.2 Clustered Redis
For larger datasets, use Redis Cluster to shard data across multiple nodes. Plan your hash slot distribution carefully and avoid hot keys.
16.3 Read replicas
Use replicas for read scaling, not write scaling. Keep write operations on the master and promote replicas only on failover.
Part 17: Monitoring and Alerting
Visibility is essential for Redis reliability.
17.1 Metrics to monitor
Track keys, memory usage, evictions, hit ratio, connected clients, and command latency.
17.2 Lambda and slowlog
Use the SLOWLOG to identify slow commands. High SLOWLOG counts often point to scan-heavy patterns or blocking commands.
SLOWLOG GET 20
17.3 Health checks
Implement health checks for both Redis service availability and replication status. A simple PING is necessary but not sufficient for cluster readiness.
Part 18: Maintenance and Operational Hygiene
Regular maintenance prevents Redis incidents.
18.1 Version upgrades
Upgrade Redis carefully. Test new versions in staging, and pay attention to compatibility notes for persistence and cluster behaviour.
18.2 Resource tuning
Tune maxmemory, eviction policy, and I/O settings based on workload.
maxmemory 4gb
maxmemory-policy allkeys-lru
18.3 Controlled restarts
Use rolling restarts for clusters and replicas. Avoid simultaneous restarts of all nodes.
Part 19: Securing Operational Commands
Some Redis commands can be dangerous in production.
19.1 Disable dangerous commands
Disable commands like FLUSHALL, FLUSHDB, DEBUG, and CONFIG for users that do not need them.
rename-command FLUSHALL ""
rename-command CONFIG ""
19.2 Audit config changes
Log when configuration commands or ACL changes occur. This protects against accidental or malicious operational changes.
Part 20: Final Redis Production Checklist
- Redis instances are isolated from public networks
- ACLs and authentication are configured for every client
- TLS is enabled for all client connections
- persistence and backup procedures are tested
- high availability is configured with Sentinel or Cluster
- monitoring captures memory, latency, and replication health
- dangerous commands are disabled or restricted
- version upgrades are tested in staging before production
A secure Redis deployment is a foundational part of a self-hosted stack. Treat it as infrastructure, not a convenience cache, and you can maintain both performance and trust.
Part 21: Advanced Redis Scaling
Scaling Redis beyond a single node requires careful planning.
21.1 Sharding strategies
Use Redis Cluster to shard keys across nodes. Choose shard boundaries that align with workload patterns and minimize cross-slot operations.
21.2 Hot key mitigation
Identify and mitigate hot keys. Use techniques such as key prefixing, secondary indexes, or caching patterns that avoid single-key overloads.
21.3 Read scaling with replicas
Add replicas for read-heavy workloads. Use min-slaves-to-write and min-slaves-max-lag to protect durability during failover.
Part 22: Persistence Tuning and Recovery
Persistence configuration balances durability, performance, and recovery time.
22.1 AOF rewrite strategy
Tune AOF rewrite thresholds so rewrite operations do not cause unacceptable latency.
aof-rewrite-percentage 100
aof-rewrite-min-size 64mb
Monitor rewrite frequency and duration.
22.2 Snapshot recovery
Test recovery from both RDB and AOF regularly. Ensure that the recovery process works with your chosen storage and file permissions.
22.3 Append-only mode tradeoffs
AOF provides better durability than RDB but can use more disk and require rewrite operations. Use a hybrid approach if you need the best of both worlds.
Part 23: Redis on Modern Infrastructure
Redis deployments on Kubernetes and containers require additional care.
23.1 StatefulSets and persistent volumes
Use Kubernetes StatefulSet for stable network identities and persistent storage. Avoid ephemeral volumes for stateful Redis nodes.
23.2 Pod disruption budgets
Protect Redis availability during cluster maintenance with Pod Disruption Budgets.
23.3 Service mesh considerations
If a service mesh is present, ensure Redis clients can connect with predictable load balancing. Avoid unnecessary sidecar proxies for latency-sensitive Redis traffic.
Part 24: Security Review and Compliance
Redis security must be reviewed regularly.
24.1 Configuration audits
Audit redis.conf and runtime settings periodically. Look for open ports, missing TLS, and disabled authentication.
24.2 Operational playbooks
Create playbooks for common Redis operations: failover, backup restore, scaling, and security incident response.
24.3 External dependencies
Review any external tooling or monitoring agents that interact with Redis. Treat them as part of the trusted computing base.
Part 25: Final Redis Reliability Checklist
- cluster and failover behavior is tested
- persistence recovery paths are validated
- memory and command latency are monitored
- ACLs and TLS are enforced everywhere
- images and host OS are scanned for vulnerabilities
- resource limits are configured for containers
- hot key and eviction policies are understood
- operational playbooks are documented and accessible
Reliable Redis deployments require both strong security and predictable operational routines. Treat Redis as critical infrastructure and maintain it with the same discipline you use for your application services.
Part 26: Memory Efficiency and Fragmentation
Redis memory behavior affects both performance and cost.
26.1 Maxmemory policies
Choose an eviction policy that matches your workload. For cache-heavy loads, allkeys-lru is common, but for session stores, volatile-lru or volatile-ttl may be safer.
26.2 Fragmentation monitoring
Monitor mem_fragmentation_ratio. A value significantly above 1.0 indicates fragmentation that can waste memory and degrade performance.
26.3 Active defragmentation
Enable active defragmentation for long-running instances.
activedefrag yes
This can improve memory efficiency without requiring restarts.
Part 27: Disaster Recovery and Incident Response
Plan for failures before they happen.
27.1 Restore drills
Run Redis restore drills from backups and AOF files. Verify that you can recover to a recent point and that the restored instance is healthy.
27.2 Failover playbooks
Document the steps for manual failover when Sentinel does not perform as expected. Include how to promote a replica and how to reintegrate the old master.
27.3 Post-incident review
After any Redis incident, review the root cause and the operational response. Update the runbook to prevent similar issues.
Part 28: Redis Security in Multi-Tenant Environments
Shared Redis clusters need strict boundaries.
28.1 Tenant isolation
Use separate databases or clusters for different tenants. Avoid placing untrusted workloads in the same logical instance as critical data.
28.2 Quota enforcement
Enforce quotas on memory, keys, and command usage for tenant-specific users. ACLs can enforce command restrictions, but resource quotas may require external tooling or separate instances.
28.3 Monitoring tenant isolation
Track usage per tenant and detect noisy neighbors early. Use metrics to identify tenants approaching their limits.
Part 29: Maintenance Windows and Upgrades
Planned maintenance keeps Redis healthy.
29.1 Maintenance scheduling
Schedule maintenance windows for cluster upgrades, failovers, and persistence tuning. Communicate them clearly to stakeholders.
29.2 Rolling upgrades
Upgrade one node at a time in clustered or replicated setups. Validate the cluster state before upgrading the next node.
29.3 Backward compatibility
Test new Redis versions with your workload before production. Some commands and persistence formats can change between versions.
Part 30: Final Redis Security and Reliability Checklist
- memory usage and fragmentation are monitored and controlled
- persistence recovery drills are scheduled and documented
- ACLs and TLS protect every client path
- cluster and sentinel behavior are tested under failover
- disaster recovery and incident response runbooks are maintained
- tenant boundaries are enforced in multi-tenant environments
- maintenance windows and upgrades follow a rolling plan
- Redis is treated as a critical backend service with observability and accountability
Secure, reliable Redis deployments are built from repeatable operations, strong isolation, and well-tested recovery practices. The work you invest in these areas pays off in uptime and trust.
Part 31: Stability and Operations
A resilient Redis deployment is one that survives both planned and unplanned events.
31.1 Operational drill cadence
Conduct Redis failover and restore drills at least quarterly. Verify both automated and manual recovery paths.
31.2 Resource planning
Plan capacity with headroom for growth. Redis memory usage can rise over time as datasets evolve, so avoid operating close to the limit.
31.3 Ongoing tuning
Review eviction, persistence, and replication settings periodically. As workload patterns change, your Redis tuning should change with them.
Part 32: Continuous Redis Improvement
A secure Redis deployment is never finished. Keep improving it as the application evolves and as threats change.
32.1 Regular security reviews
Review Redis security settings and ACLs at least every quarter. Incorporate new security guidance and remove deprecated commands or weak cipher settings.
32.2 Performance tuning reviews
Revisit memory and eviction strategies when usage patterns shift. A cache-heavy workload today may become a session store tomorrow, and the tuning should reflect the new behavior.
32.3 Organizational communication
Keep stakeholders informed when Redis availability, scaling, or security posture changes. Clear communication prevents unexpected surprises during deployments and incident response.
Part 33: Redis as a First-Class Service
Treat Redis like any other critical service in your stack. That means documentation, testing, monitoring, and regular reviews are all part of its lifecycle.
33.1 Lifecycle ownership
Assign clear ownership for Redis operations, security, and capacity planning. When Redis has a dedicated steward, issues are detected and resolved faster.
Further Reading
- Docker Compose Tutorial 2026 — run Redis in Docker with your application stack
- PostgreSQL 17 Performance Tuning — database-level caching with pgBouncer connection pooling
- Python for DevOps Automation — automation scripts using the Redis connection patterns shown here
Tested on: Ubuntu 24.04 LTS (Hetzner CX22). Redis 7.4.0. Last verified: April 29, 2026.