cheat-sheets

Redis

Redis is an in-memory data store used as a cache, session store, queue and simple database. It keeps data in RAM and can persist it to disk with snapshots (RDB) and an append-only file (AOF). Valkey is a compatible fork that uses the same commands and redis-cli-style tools.

Documentation: Redis docs · Commands · redis-cli · Persistence

Verification: the redis-cli options (--bigkeys, --memkeys, --keystats, --scan, --latency) and the Docker image tags were checked against the Redis docs and Docker Hub. Not verified against the docs: ACL, replication and persistence settings below (they come from the Redis documentation as known, not re-read). No command was executed. Commands like FLUSHALL and KEYS * are dangerous on a real instance.

See also: Docker · Docker-Compose · PostgreSQL Cheat-Sheet · MongoDB · Linux · Linux Performance Troubleshooting


Run in Docker #

bash
docker run -d --name redis --restart unless-stopped \
  -p 127.0.0.1:6379:6379 \
  -v redis-data:/data \
  redis:8 \
  redis-server --appendonly yes --requirepass <PASSWORD>

docker exec -it redis redis-cli -a '<PASSWORD>' ping

Compose:

yaml
services:
  redis:
    image: redis:8
    restart: unless-stopped
    command: ["redis-server", "--appendonly", "yes", "--maxmemory", "256mb", "--maxmemory-policy", "allkeys-lru"]
    volumes:
      - redis-data:/data
    ports:
      - "127.0.0.1:6379:6379"
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 3s
      retries: 5
volumes:
  redis-data:

Mount /data or the data is lost with the container. Do not expose port 6379 to the internet. See Docker and Docker-Compose. Prefer --requirepass or an ACL file over a password on the command line in production (it shows in ps). Pin a major version tag (redis:7, redis:8).

Install on Ubuntu / Debian #

bash
sudo apt update && sudo apt install -y redis-server
sudo systemctl enable --now redis-server
redis-cli ping

Config: /etc/redis/redis.conf. For a current version use the official packages repository.


redis-cli #

COMMANDDESCRIPTION
redis-cliConnect to 127.0.0.1:6379
redis-cli -h <HOST> -p 6379 -a <PASSWORD>Remote with password (warns that it is insecure; prefer REDISCLI_AUTH)
REDISCLI_AUTH=<PASSWORD> redis-cliPassword from the environment
redis-cli --user <USER> --pass <PASSWORD>ACL user
redis-cli -n 2Select database 2
redis-cli --tls -h <HOST>TLS connection
redis-cli pingReturns PONG
redis-cli INFOFull server info (INFO memory, INFO stats, INFO replication)
redis-cli -r 5 -i 1 INFO clientsRepeat every second, 5 times
redis-cli MONITORStream every command (heavy, debugging only)
redis-cli --scan --pattern 'user:*'Iterate keys safely (use instead of KEYS)
redis-cli --scan --pattern 'sess:*' | xargs -L 100 redis-cli DELDelete keys matching a pattern, in batches
redis-cli --bigkeysSample the keyspace and report the largest key of each type
redis-cli --memkeysSame, by memory use
redis-cli --keystatsCombined key size and memory distribution (recent versions)
redis-cli --latencyContinuous round-trip latency
redis-cli --latency-historyLatency in time slices
redis-cli --intrinsic-latency 5Host baseline latency (run on the server)
redis-cli --statRolling stats line
redis-cli --rdb backup.rdbDownload an RDB snapshot from a server
redis-cli -x SET key < fileRead the value from stdin
redis-cli --pipe < commands.txtFast bulk load of raw commands

--bigkeys, --memkeys and --keystats scan the whole keyspace. Run them against a replica or off-hours on large instances.

Inside redis-cli #

COMMANDDESCRIPTION
SELECT 1Switch database (0-15 by default)
DBSIZENumber of keys
SCAN 0 MATCH user:* COUNT 100Cursor-based iteration. Repeat with the returned cursor until 0
TYPE keyType of a key
TTL key / PTTL keySeconds / milliseconds to expiry (-1 none, -2 missing)
EXPIRE key 3600Set a TTL
PERSIST keyRemove the TTL
EXISTS key1 or 0
DEL keyDelete (blocks on huge keys)
UNLINK keyDelete in the background (use for large keys)
RENAME old newRename
MEMORY USAGE keyBytes used by a key
OBJECT ENCODING keyInternal encoding
FLUSHDB ASYNCDelete all keys in the current database
FLUSHALL ASYNCDelete every key in every database. Destructive
CONFIG GET maxmemory*Read settings
CONFIG SET maxmemory 256mbChange at runtime (then CONFIG REWRITE to persist to the config file)
CLIENT LISTConnected clients
SLOWLOG GET 10Last 10 slow commands
LATENCY DOCTORLatency analysis report
MEMORY DOCTORMemory advice

Data Types #

TYPECOMMANDSUSE
StringSET k v, GET k, INCR k, SET k v EX 60 NX, MSET, APPENDCache values, counters, locks (SET lock id NX EX 30)
HashHSET user:1 name alice age 30, HGET, HGETALL, HINCRBY, HDELObjects with fields
ListLPUSH, RPUSH, LPOP, BRPOP q 0, LRANGE q 0 -1, LLENQueues and stacks
SetSADD, SMEMBERS, SISMEMBER, SINTER, SUNION, SCARDUnique members, tags
Sorted setZADD board 100 alice, ZRANGE board 0 -1 WITHSCORES, ZREVRANGE, ZINCRBY, ZRANKLeaderboards, rate limits, schedulers
StreamXADD s * k v, XRANGE s - +, XREAD, XGROUP CREATE, XREADGROUP, XACKEvent logs, consumer groups
Bitmap / HyperLogLogSETBIT, BITCOUNT, PFADD, PFCOUNTFlags, approximate unique counts
GeoGEOADD, GEOSEARCHLocation lookups
Pub/SubSUBSCRIBE ch, PUBLISH ch msgFire-and-forget messages (not stored)
SET greeting "hello" EX 300
HSET user:1 name alice email alice@example.com
HGETALL user:1
RPUSH jobs '{"id":1}'
BRPOP jobs 5
ZADD scores 42 alice 17 bob
ZREVRANGE scores 0 9 WITHSCORES

Use a naming convention such as app:object:id and always set TTLs on cache keys.


Persistence #

MODEWHATTRADE-OFF
RDBPoint-in-time snapshots, written to dump.rdbCompact, fast restart, can lose the last few minutes
AOFLogs every write, replayed on start (appendonly yes)Less data loss (appendfsync everysec loses at most about 1 s), bigger files, slower restart
RDB + AOFBoth on. At startup Redis loads the AOFCommon choice for data you cannot lose
Nonesave "" and appendonly noPure cache

redis.conf:

# RDB: snapshot after 3600 s if >=1 change, 300 s if >=100, 60 s if >=10000
save 3600 1 300 100 60 10000
dbfilename dump.rdb
dir /data

# AOF
appendonly yes
appendfsync everysec
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
COMMANDDESCRIPTION
BGSAVEStart an RDB snapshot in the background
LASTSAVEUnix time of the last successful save
BGREWRITEAOFCompact the AOF in the background
INFO persistenceStatus of RDB and AOF
CONFIG SET appendonly yesTurn AOF on at runtime

Back up by copying dump.rdb (after BGSAVE) or the AOF directory (appendonlydir/ in 7+) while Redis runs, or with redis-cli --rdb. To restore, stop Redis, put the file in dir, start. If AOF is enabled it takes precedence over dump.rdb on start, so move the old AOF away or restore the AOF itself. Keep copies off the host.

Memory and eviction:

maxmemory 512mb
maxmemory-policy allkeys-lru
POLICYEVICTS
noevictionNothing. Writes fail when full (default)
allkeys-lru / allkeys-lfuAny key, least recently or frequently used. Good for caches
volatile-lru / volatile-ttlOnly keys with a TTL
allkeys-randomRandom

Run Redis with vm.overcommit_memory=1 on the host so snapshots and rewrites (which fork) do not fail: echo 'vm.overcommit_memory = 1' | sudo tee /etc/sysctl.d/99-redis.conf && sudo sysctl --system. Disable Transparent Huge Pages if Redis warns about it.


Security and ACLs #

Defaults: bind to localhost only, protected mode on. Keep it that way, and always use a password or ACL when it is reachable by anything but localhost.

redis.conf basics:

bind 127.0.0.1 -::1
protected-mode yes
requirepass <LONG-RANDOM-PASSWORD>
rename-command FLUSHALL ""

(rename-command is deprecated: prefer ACLs.)

ACLs (Redis 6+):

COMMANDDESCRIPTION
ACL LISTAll users and rules
ACL WHOAMICurrent user
ACL SETUSER app on '>S3cretPassw0rd' '~app:*' '&*' +@read +@write -@dangerousCreate user app: enabled, password, keys matching app:*, all pub/sub channels, read and write commands, no dangerous commands
ACL SETUSER readonly on '>Pass' '~*' +@readRead-only user
ACL SETUSER default offDisable the default user (after a replacement admin exists)
ACL DELUSER appDelete a user
ACL CATCommand categories
ACL GETUSER appShow one user
ACL LOGRecent denied attempts
ACL SAVE / ACL LOADWrite / read the ACL file (aclfile /etc/redis/users.acl)

Rule syntax: on|off, >password, ~keypattern, &channelpattern, +command, -command, +@category. The passwords above are placeholders: use your own and keep them out of shell history.

Use TLS for traffic across hosts (tls-port, tls-cert-file, tls-key-file, tls-ca-cert-file), or keep Redis on a private network or a WireGuard tunnel.


Replication #

A replica copies a primary asynchronously and serves reads.

On the replica (redis.conf) or at runtime:

replicaof <PRIMARY-HOST> 6379
masterauth <PRIMARY-PASSWORD>
masteruser <ACL-USER-IF-USED>
replica-read-only yes
COMMANDDESCRIPTION
REPLICAOF <HOST> 6379Make this server a replica now
REPLICAOF NO ONEPromote a replica to primary
INFO replicationRole, connected replicas, offset, master_link_status
ROLEShort role and offset view
WAIT 1 100Block until 1 replica acknowledged the writes, or 100 ms pass
CONFIG SET min-replicas-to-write 1Refuse writes if fewer than 1 replica is connected

Notes:

  • Replication is asynchronous. A failover can lose the last writes.
  • A new replica does a full sync: the primary forks, writes an RDB and sends it. Plan memory headroom.
  • Automatic failover needs Redis Sentinel (three or more sentinels, SENTINEL config, clients that support it) or Redis Cluster for sharding. For a homelab a single instance with AOF is usually enough.
  • Docker: give the replica command: redis-server --replicaof redis 6379 on a shared network.

Troubleshooting #

SYMPTOMCHECK
High memoryINFO memory, redis-cli --bigkeys, MEMORY USAGE key, add TTLs, set maxmemory
Slow commandsSLOWLOG GET 10, avoid KEYS *, big HGETALL/SMEMBERS, use SCAN/UNLINK
Latency spikesredis-cli --latency, LATENCY DOCTOR, fork time from snapshots (INFO stats latest_fork_usec), swapping
MISCONF Redis is configured to save RDB snapshots, but it's currently unable to persistDisk full or no write permission on dir. Check df -h and file ownership
OOM command not allowed when used memory > 'maxmemory'Raise maxmemory or set an eviction policy
NOAUTH Authentication requiredPass the password (-a, REDISCLI_AUTH)
DENIED Redis is running in protected modeIt is listening on a non-loopback address without a password: set requirepass/ACL first
Keys vanishTTLs, eviction policy, a FLUSHALL, or a non-persistent restart
Replica stuck syncingINFO replication, primary logs, repl-timeout, client-output-buffer-limit replica

redis-benchmark -q -n 100000 gives a quick throughput test (run it against a test instance).

Search all sheets

Tip: / or Ctrl/Cmd+K to open, Esc to close.