I added Redis to a web app that was struggling with database load. The app was hitting the database for the same expensive queries on every page load — counts, aggregations, things that didn't change more than once per minute.
Adding Redis caching to those queries dropped the average response time significantly. The database went from being the bottleneck to being mostly idle. That was the moment I understood what Redis is actually for — not storing primary data, but keeping frequently-accessed data in memory so you're not recomputing it constantly.
This guide covers installing Redis on Ubuntu 22.04, securing it with a password and firewall, and the three main use cases: caching, session storage, and rate limiting.
I run Redis on Tencent Cloud Lighthouse alongside the main application. Redis uses very little RAM for typical caching workloads — 64–128 MB covers most scenarios, so even the entry-level Lighthouse plan leaves plenty of headroom. Running Redis on the same instance as your application means sub-millisecond latency between them (localhost communication), which is where the performance benefit of caching is most pronounced. Lighthouse's OrcaTerm browser terminal makes it easy to connect to
redis-cliand inspect cached keys without needing a local SSH setup.
- Key Takeaways
| Use case | What it does | Impact |
|---|---|---|
| Database query cache | Store results of expensive queries in memory | Response time: 200ms → 2ms |
| Session storage | Store user sessions in Redis instead of database | Eliminates session DB queries |
| Rate limiting | Count requests per IP per time window | API abuse prevention |
| Job queues | Store background jobs for workers | Decoupled async processing |
| Pub/Sub messaging | Broadcast events to subscribers | Real-time features |
| Leaderboards | Sorted sets for ranking | Game scores, trending content |
sudo apt update
sudo apt install -y redis-server
sudo systemctl start redis-server
sudo systemctl enable redis-server
# Verify
sudo systemctl status redis-server
redis-cli ping
# Should return: PONG
Check the Redis version:
redis-server --version
# Redis server v=7.x.x
By default, Redis has no password and accepts connections from any local process. Setting a password prevents unauthorized access:
sudo nano /etc/redis/redis.conf
Find the requirepass line and set a strong password:
# Uncomment and set:
requirepass your_very_strong_redis_password_here
Also disable potentially dangerous commands in production:
# Rename dangerous commands (empty string = disable)
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command CONFIG "REDIS_CONFIG_RENAMED"
rename-command DEBUG ""
Apply changes:
sudo systemctl restart redis-server
Test that authentication is required:
redis-cli ping
# (error) NOAUTH Authentication required
redis-cli -a your_password ping
# PONG
sudo nano /etc/redis/redis.conf
Key settings:
# Bind to localhost only (change if remote access needed)
bind 127.0.0.1 -::1
# Maximum memory limit (set based on available RAM)
# Leave room for the OS and other services
maxmemory 256mb
# Eviction policy when maxmemory is reached
# allkeys-lru: evict least recently used keys (good for caching)
# volatile-lru: only evict keys with expiry set
# noeviction: return errors when memory full (for queues where data loss is unacceptable)
maxmemory-policy allkeys-lru
# Persistence: save to disk periodically
# Format: save <seconds> <changes>
save 900 1 # Save if 1 key changed in 900 seconds
save 300 10 # Save if 10 keys changed in 300 seconds
save 60 10000 # Save if 10000 keys changed in 60 seconds
# Or disable persistence entirely (faster, no data survives restart):
# save ""
# Log level
loglevel notice
logfile /var/log/redis/redis-server.log
# Slow log (log commands taking > 10ms)
slowlog-log-slower-than 10000
slowlog-max-len 128
sudo systemctl restart redis-server
Redis should not be accessible from the public internet:
# Verify Redis is only listening on localhost
sudo netstat -tlnp | grep 6379
# Should show: 127.0.0.1:6379
# UFW: don't open port 6379 publicly
# If you need remote access, use SSH tunnel (see Part 8)
npm install ioredis
const Redis = require('ioredis');
const redis = new Redis({
host: '127.0.0.1',
port: 6379,
password: 'your_redis_password',
retryStrategy: (times) => Math.min(times * 50, 2000),
});
// Basic cache operations
async function cacheExample() {
// Set a key with 1 hour expiry
await redis.set('user:1', JSON.stringify({ name: 'Alice', role: 'admin' }), 'EX', 3600);
// Get cached value
const cached = await redis.get('user:1');
const user = cached ? JSON.parse(cached) : null;
console.log(user);
// Delete a key
await redis.del('user:1');
}
// Cache-aside pattern (check cache, fall back to DB)
async function getCachedUser(userId) {
const cacheKey = `user:${userId}`;
// Check cache first
const cached = await redis.get(cacheKey);
if (cached) {
return JSON.parse(cached);
}
// Miss: fetch from database
const user = await db.query('SELECT * FROM users WHERE id = $1', [userId]);
// Store in cache for 1 hour
await redis.set(cacheKey, JSON.stringify(user), 'EX', 3600);
return user;
}
// Rate limiting
async function rateLimit(ipAddress, limit = 100, windowSeconds = 60) {
const key = `ratelimit:${ipAddress}`;
const current = await redis.incr(key);
if (current === 1) {
await redis.expire(key, windowSeconds);
}
return current <= limit;
}
pip install redis
import redis
import json
from functools import wraps
r = redis.Redis(
host='127.0.0.1',
port=6379,
password='your_redis_password',
decode_responses=True # Return strings instead of bytes
)
# Test connection
r.ping() # True
# Basic operations
r.set('key', 'value', ex=3600) # Set with 1 hour TTL
value = r.get('key')
# Cache decorator
def cache(ttl=300):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
cache_key = f"{func.__name__}:{args}:{kwargs}"
cached = r.get(cache_key)
if cached:
return json.loads(cached)
result = func(*args, **kwargs)
r.set(cache_key, json.dumps(result), ex=ttl)
return result
return wrapper
return decorator
@cache(ttl=600)
def get_user_profile(user_id):
# This result is cached for 10 minutes
return db.query(f"SELECT * FROM users WHERE id = {user_id}")
For WordPress, the Redis Object Cache plugin integrates Redis for full-page caching and object caching:
# Install Redis PHP extension
sudo apt install -y php-redis
sudo systemctl restart php8.2-fpm
Install the "Redis Object Cache" plugin in WordPress, then add to wp-config.php:
define('WP_REDIS_HOST', '127.0.0.1');
define('WP_REDIS_PORT', 6379);
define('WP_REDIS_PASSWORD', 'your_redis_password');
define('WP_REDIS_DATABASE', 0);
define('WP_CACHE', true);
Go to WordPress Settings → Redis Object Cache → Enable Object Cache. This caches database query results — for a content-heavy WordPress site, the performance improvement is significant.
For managing Redis with a GUI tool (like RedisInsight) from your local machine:
# On your local machine: tunnel port 6380 to Redis on the server
ssh -L 6380:127.0.0.1:6379 ubuntu@YOUR_SERVER_IP -N
# Connect Redis CLI locally
redis-cli -p 6380 -a your_password
# Or connect RedisInsight to localhost:6380
Redis is an in-memory store. If the server restarts and persistence is disabled (or the last save was a while ago), you lose data.
For use as a cache, this is fine — the cache is rebuilt from the database on miss.
For queues, sessions, or any data where loss is unacceptable, configure persistence appropriately:
RDB snapshots (default): saves the dataset to disk periodically. Fast, but loses data between snapshots.
AOF (Append-Only File): logs every write operation. Slower but minimal data loss.
# Enable AOF in redis.conf
appendonly yes
appendfsync everysec # Sync to disk every second
For a queue system running in production, use AOF. For a pure cache, RDB or no persistence is fine.
# Connect
redis-cli -a YOUR_PASSWORD
# In redis-cli
PING # Test connection
SET key value # Set a key
SET key value EX 3600 # Set with 1 hour TTL
GET key # Get value
DEL key # Delete key
EXISTS key # Check if key exists
TTL key # Check remaining TTL (-1 = no expiry, -2 = not found)
EXPIRE key 3600 # Set TTL on existing key
KEYS pattern # List keys (avoid on large databases)
SCAN 0 MATCH prefix:* COUNT 100 # Better: iterate keys safely
# Strings
INCR counter # Increment by 1
INCRBY counter 5 # Increment by 5
# Lists (FIFO queue)
RPUSH queue "job1" # Push to right
LPOP queue # Pop from left
# Sorted sets
ZADD leaderboard 100 "player1"
ZREVRANGE leaderboard 0 9 WITHSCORES # Top 10
# Server info
INFO # Full server stats
INFO memory # Memory usage
DBSIZE # Number of keys
SLOWLOG GET 10 # Last 10 slow commands
FLUSHDB # Delete all keys (current DB) — be careful!
| Issue | Likely Cause | Fix |
|---|---|---|
| Connection refused | Service not running or wrong port | Check systemctl status SERVICE and verify firewall rules |
| Permission denied | Wrong file ownership or permissions | Check file ownership with ls -la and use chown/chmod to fix |
| 502 Bad Gateway | Backend service not running | Restart the backend service; check logs with journalctl -u SERVICE |
| SSL certificate error | Certificate expired or domain mismatch | Run sudo certbot renew and verify domain DNS points to server IP |
| Service not starting | Config error or missing dependency | Check logs with journalctl -u SERVICE -n 50 for specific error |
| Out of disk space | Logs or data accumulation | Run df -h to identify usage; clean logs or attach CBS storage |
| High memory usage | Too many processes or memory leak | Check with htop; consider upgrading instance plan if consistently high |
| Firewall blocking traffic | Port not open in UFW or Lighthouse console | Open port in Lighthouse console firewall AND sudo ufw allow PORT |
How long does it take to set up Redis on a cloud server?
With the appropriate Lighthouse application image (if available), setup takes 10–30 minutes. Manual installation from a plain Ubuntu image typically takes 30–90 minutes following this guide.
What server specifications do I need for Redis?
Check the prerequisites section of this guide for specific requirements. As a general rule: start with the minimum recommended spec, monitor actual usage, and upgrade from the Lighthouse console if needed.
How do I keep Redis updated?
Follow the update procedure specific to how it was installed (package manager, Docker pull, or binary replacement). Take a Lighthouse snapshot before any major update as a safety net.
How do I back up Redis data?
Use Lighthouse snapshots for full-server recovery plus the application's own export/backup mechanism for granular recovery. Both together provide comprehensive backup coverage.
htop and expand the server spec or attach CBS storage as needed.Add Redis to your server today:
👉 Tencent Cloud Lighthouse — Ubuntu VPS for your application stack
👉 View current pricing and promotions
👉 Explore all active deals and offers