| name | redis |
| description | Redis mastery for caching, data structures, pub/sub, streams, Lua scripting, clustering, and CLI operations. Use when user asks to "set up Redis", "cache data", "redis commands", "pub/sub", "redis data types", "session store", "rate limiting with Redis", "distributed lock", "redis streams", "redis cluster", "redis sentinel", "Lua scripting in Redis", "redis transactions", "redis persistence", "redis monitoring", or any Redis tasks. |
Redis
Caching, data structures, and real-time patterns.
Key Naming Conventions
object-type:id:field # Colon-separated hierarchy
user:1001:profile # User profile
cache:api:/v2/products # API response cache
session:abc123 # Session data
ratelimit:ip:10.0.0.1 # Rate limit counter
lock:order:7890 # Distributed lock
Keep keys short but readable. Colons are convention, not syntax. Avoid KEYS in production — use SCAN.
CLI Basics
redis-cli
redis-cli -h hostname -p 6379 -a password
redis-cli --tls -h hostname -p 6380
redis-cli -u redis://user:pass@host:6379/0
redis-cli ping
redis-cli info memory
redis-cli --stat
redis-cli --bigkeys
redis-cli --memkeys
redis-cli --latency
redis-cli --scan --pattern "user:*" | head -20
redis-cli DBSIZE
Strings
SET key "value"
GET key
SET session:abc "user123" EX 3600
SET key "val" PX 5000
SET key "val" EXAT 1700000000
SET lock:res "owner" NX EX 30
SET key "val" XX
INCR counter
INCRBY counter 5
DECR counter
INCRBYFLOAT price 2.50
MSET key1 "val1" key2 "val2"
MGET key1 key2
APPEND key " suffix"
STRLEN key
GETRANGE key 0 4
Hashes
HSET user:1 name "Alice" email "alice@test.com" age 30
HGET user:1 name
HGETALL user:1
HMGET user:1 name email
HINCRBY user:1 age 1
HINCRBYFLOAT user:1 balance 9.99
HEXISTS user:1 email
HDEL user:1 age
HLEN user:1
HKEYS user:1
HSCAN user:1 0 MATCH "n*" COUNT 10
Lists
LPUSH queue "task1"
RPUSH queue "task2"
LPOP queue
RPOP queue
BLPOP queue 30
LRANGE queue 0 -1
LLEN queue
LTRIM queue 0 99
LPOS queue "task1"
LMOVE src dst LEFT RIGHT
Sets and Sorted Sets
SADD tags "python" "redis" "docker"
SREM tags "docker"
SISMEMBER tags "python"
SMEMBERS tags
SCARD tags
SUNION tags1 tags2
SINTER tags1 tags2
SDIFF tags1 tags2
SRANDMEMBER tags 2
SPOP tags
SSCAN tags 0 MATCH "p*" COUNT 100
ZADD leaderboard 100 "alice" 95 "bob" 87 "charlie"
ZRANGE leaderboard 0 -1 WITHSCORES
ZREVRANGE leaderboard 0 2 WITHSCORES
ZRANGEBYSCORE leaderboard 90 100
ZRANGEBYSCORE leaderboard -inf +inf LIMIT 0 10
ZRANK leaderboard "alice"
ZREVRANK leaderboard "alice"
ZINCRBY leaderboard 5 "bob"
ZCOUNT leaderboard 80 100
ZSCORE leaderboard "alice"
ZPOPMIN leaderboard
ZPOPMAX leaderboard
ZUNIONSTORE dest 2 board1 board2 WEIGHTS 1 2
Streams, HyperLogLog, and Bitmaps
XADD events * action "click" page "/home"
XLEN events
XRANGE events - + COUNT 10
XREAD COUNT 5 BLOCK 2000 STREAMS events $
XGROUP CREATE events mygroup $ MKSTREAM
XREADGROUP GROUP mygroup consumer1 COUNT 1 BLOCK 2000 STREAMS events >
XACK events mygroup <message-id>
XPENDING events mygroup
XCLAIM events mygroup consumer2 3600000 <id>
PFADD unique_visitors "user1" "user2" "user3"
PFCOUNT unique_visitors
PFMERGE total daily:mon daily:tue
SETBIT logins:2024-01-15 1001 1
GETBIT logins:2024-01-15 1001
BITCOUNT logins:2024-01-15
BITOP AND active_both logins:day1 logins:day2
Key Management and TTL
SCAN 0 MATCH user:* COUNT 100
EXPIRE key 3600
PEXPIRE key 3600000
EXPIREAT key 1700000000
TTL key
PERSIST key
DEL key
UNLINK key
TYPE key
OBJECT ENCODING key
MEMORY USAGE key
EXISTS key key2
RENAME key newkey
DUMP key
RESTORE newkey 0 <bytes>
Always set TTLs on cache keys. Jitter TTLs (add random seconds) to prevent thundering herd on mass expiry. Use EXPIREAT for calendar-aligned expirations.
Pub/Sub
SUBSCRIBE channel1 channel2
PSUBSCRIBE news.*
PUBLISH channel1 "Hello subscribers!"
PUBSUB CHANNELS
PUBSUB NUMSUB channel1
Limitations: fire-and-forget (no persistence, no replay). Subscribers miss messages during disconnection. No acknowledgment. For durable messaging, use Streams with consumer groups.
Caching Patterns
GET cache:user:1
SET cache:user:1 '{"name":"Alice"}' EX 300
Session Storage
HSET session:sid123 userId 1 role "admin" cart '["item1"]' lastAccess 1700000000
EXPIRE session:sid123 86400
HGET session:sid123 role
HSET session:sid123 lastAccess 1700000001
EXPIRE session:sid123 86400
Rate Limiting
INCR ratelimit:user:1:1700000000
EXPIRE ratelimit:user:1:1700000000 60
ZADD ratelimit:user:1 <now_ms> <request_id>
ZREMRANGEBYSCORE ratelimit:user:1 0 <now_ms - window_ms>
ZCARD ratelimit:user:1
EXPIRE ratelimit:user:1 <window_seconds>
Distributed Lock (Redlock)
SET lock:resource <unique-id> NX EX 30
EVAL "if redis.call('GET',KEYS[1]) == ARGV[1] then return redis.call('DEL',KEYS[1]) else return 0 end" 1 lock:resource <unique-id>
Transactions
MULTI
SET user:1:balance 100
INCR stats:transactions
EXEC
WATCH user:1:balance
balance = GET user:1:balance
MULTI
SET user:1:balance <new-value>
EXEC
DISCARD
Redis transactions are not rollback-capable. If a command fails inside EXEC, other commands still execute. Use Lua scripts for true atomic logic.
Lua Scripting
EVAL "return redis.call('SET', KEYS[1], ARGV[1])" 1 mykey "myval"
EVAL "
local cur = redis.call('GET', KEYS[1])
if cur == ARGV[1] then
redis.call('SET', KEYS[1], ARGV[2])
return 1
end
return 0
" 1 mykey "old" "new"
SCRIPT LOAD "return redis.call('GET', KEYS[1])"
EVALSHA a42059b356c875f0717db19a51f6aaa9161571a2 1 mykey
SCRIPT EXISTS <sha>
EVAL "
local tokens = tonumber(redis.call('GET', KEYS[1]) or ARGV[1])
if tokens > 0 then
redis.call('SET', KEYS[1], tokens - 1, 'EX', ARGV[2])
return 1
end
return 0
" 1 bucket:user:1 "10" "60"
Persistence
CONFIG SET save "900 1 300 10 60 10000"
BGSAVE
CONFIG SET appendonly yes
CONFIG SET appendfsync everysec
BGREWRITEAOF
CONFIG SET aof-use-rdb-preamble yes
RDB: faster restarts, smaller files, possible data loss between snapshots. AOF: more durable, larger files. Hybrid: recommended for production.
Redis Sentinel (High Availability)
redis-cli -p 26379 SENTINEL masters
redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster
redis-cli -p 26379 SENTINEL replicas mymaster
Sentinel monitors master and auto-promotes a replica on failure. Clients connect via Sentinel to discover the current master.
Redis Cluster (Sharding)
redis-cli --cluster create host1:6379 host2:6379 host3:6379 \
--cluster-replicas 1
redis-cli --cluster info host1:6379
redis-cli --cluster check host1:6379
redis-cli --cluster reshard host1:6379
redis-cli -c -h host1 -p 6379
SET {user:1}:profile '...'
SET {user:1}:settings '...'
Multi-key commands (MGET, transactions) only work on keys in the same hash slot. Use hash tags {...} to colocate related keys.
Memory Optimization
CONFIG SET maxmemory 256mb
CONFIG SET maxmemory-policy allkeys-lru
INFO memory
MEMORY DOCTOR
MEMORY USAGE key SAMPLES 5
redis-cli --bigkeys
Use hashes for small objects (ziplist encoding). Avoid large blobs — offload to object storage, cache references.
Connection Pooling
import redis
pool = redis.ConnectionPool(host='localhost', port=6379, db=0,
max_connections=20, decode_responses=True)
r = redis.Redis(connection_pool=pool)
Never create a new connection per request. Set max_connections based on concurrency. Use timeout and retry_on_timeout.
Monitoring
INFO all
INFO stats
INFO clients
INFO replication
SLOWLOG GET 10
CONFIG SET slowlog-log-slower-than 10000
MONITOR
CONFIG SET latency-monitor-threshold 100
LATENCY LATEST
CLIENT LIST
CLIENT SETNAME "myapp-worker-1"
Common Patterns
ZADD leaderboard 100 "player:1"
ZINCRBY leaderboard 5 "player:1"
ZREVRANGE leaderboard 0 9 WITHSCORES
GEOADD locations -122.4194 37.7749 "san_francisco"
GEODIST locations "san_francisco" "new_york" km
GEOSEARCH locations FROMLONLAT -122.0 37.0 BYRADIUS 100 km ASC
LPUSH feed:user:1 '{"action":"post","id":42}'
LTRIM feed:user:1 0 99
SET idempotent:req:abc123 1 NX EX 86400
Reference
For caching patterns, pub/sub, and Lua scripts: references/patterns.md