Redis Cheatsheet - 40+ Commands, Keys & Expire
For developers using Redis as a cache who must care about memory and TTL strategy. The commands are easy, but big keys blowing up memory, hot keys concentrating load on one node, and cache penetration/avalanche are the real business problems. By the end you can pick the right command per data structure, use INFO memory and object encoding to find top memory consumers, understand the RDB/AOF persistence trade-off, and use SCAN/UNLINK to handle big keys without blocking the instance.
Typical Use Case
Caching and key-value store ops: connect, basic read/write, inspect memory and keyspace, troubleshoot memory growth, cache stampede/avalanche, connection exhaustion, and RDB/AOF persistence and recovery.
Connection 6
redis-cli -h 127.0.0.1 -p 6379 -a passwordredis-cli --scan --pattern "user:*"redis-cli -r 5 -i 1 INFO memoryAUTH passwordSELECT 0DBSIZEData Structure 11
SET key value EX 300GET keyMSET k1 v1 k2 v2HSET user:1 name "tom" age 30HGETALL user:1LPUSH queue task1BRPOP queue 30ZADD rank 100 "user1" 200 "user2"ZRANGE rank 0 -1 WITHSCORESSADD tags "python" "redis"SINTER set1 set2Key Space 8
EXPIRE key 300TTL keyTYPE keyDEL key1 key2UNLINK keyRENAME old_key new_keyRANDOMKEYOBJECT ENCODING keyPersistence & Memory 7
BGSAVELASTSAVEBGREWRITEAOFINFO memoryMEMORY USAGE keyCONFIG GET maxmemoryCONFIG GET maxmemory-policySlowlog & Monitor 6
SLOWLOG GET 10SLOWLOG RESETCONFIG GET slowlog-log-slower-thanCLIENT LISTCLIENT KILL ID <id>INFO clientsCluster & Replication 5
CLUSTER INFOCLUSTER NODESCLUSTER KEYSLOT keyINFO replicationROLEParameter matrix
| Parameter | Effect | Example |
|---|---|---|
-h | Host to connect to. | redis-cli -h 127.0.0.1 |
-p | Port to connect to; Redis listens on 6379 by default. | redis-cli -p 6380 |
-a | Password passed on the command line; prefer --user when the account is an ACL user. | redis-cli -a secret |
--scan | Walk the keyspace incrementally instead of blocking the server the way KEYS does. | redis-cli --scan --pattern "session:*" | head |
INFO memory | Report memory usage and fragmentation for the running instance. | redis-cli INFO memory |
EXPIRE | Attach a time-to-live, in seconds, to a key. | EXPIRE token:1 3600 |
TTL | Show how many seconds remain before the key expires. | TTL token:1 |
CONFIG SET | Change a setting while the server keeps running; a few options still need a restart. | redis-cli CONFIG SET maxmemory 2gb |
SAVE/BGSAVE | Write an RDB snapshot, either blocking or in the background. | redis-cli BGSAVE |
FLUSHDB | Erase every key in the current database. Destructive. | redis-cli FLUSHDB |
Common pitfalls
SymptomMemory climbs without bound until keys start being evicted at maxmemory, or the process is OOM-killed.
CauseKeys carry no expiry, one key holds an oversized hash or list, or a client-side cache grows with no bound.
FixGive every cache key a TTL, find the oversized keys with redis-cli --bigkeys and split them, and pick a maxmemory-policy that suits the workload such as allkeys-lru.
SymptomA KEYS * call wedges the server and clients time out in a wave.
CauseKEYS walks the entire keyspace in one command, and the server is single-threaded.
FixIterate with SCAN or redis-cli --scan instead. Never run KEYS * in production, and rename the command out of reach if you can.
SymptomCached entries all expire together and a flood of traffic lands on the database.
CauseA large batch of keys shares the same expiry second, which is a cache avalanche, or a single hot key disappears, which is a stampede.
FixAdd jitter to every TTL so they do not line up, rebuild hot keys behind a mutex or a logical expiry, and rate-limit on the database side.
SymptomEverything is gone after a restart.
CauseOnly RDB is enabled with a long interval between snapshots, or AOF is off and the crash landed between two of them.
FixEnable AOF (appendonly yes) with an fsync policy matched to how much loss you can absorb, and keep both persistence paths for anything critical.
SymptomThe connection count maxes out and new clients are refused.
CauseClients open a connection per request and never release it, or maxclients is simply set too low.
FixReuse a connection pool, trace the offending clients with redis-cli CLIENT LIST, raise maxclients, and fix the code that leaks sockets.
SymptomSomeone ran FLUSHDB or FLUSHALL and the data is gone.
CauseA cleanup command ran against the live server with nothing durable behind it, and any replica replicated the deletion.
FixRename the dangerous commands out of reach, recover from the AOF or the latest RDB, and as a last resort rebuild from a replica or a backup.
Troubleshooting
1Inspect memory usage and fragmentation
redis-cli INFO memoryRead used_memory_human and mem_fragmentation_ratio; anything above 1.5 points to fragmentation worth investigating.
2Locate the oversized keys and the type mix
redis-cli --bigkeysFinds the big hashes, lists and sets worth splitting so a single key can never stall the server on its own.
3Walk the keyspace without blocking
redis-cli --scan --pattern "session:*" | wc -lReplaces KEYS with an incremental cursor, so the server keeps serving other clients throughout.
4See which clients are connected
redis-cli CLIENT LISTLists client addresses and idle time, which is how a leaking connection pool gives itself away.
Command Examples
Clear prefixed keys with SCAN instead of KEYS
redis-cli --scan --pattern "session:*" | xargs -r -n 500 redis-cli DELWhen you must clear session-style prefixed keys, KEYS blocks the whole instance while it walks the keyspace. SCAN returns a small cursor batch at a time; combined with --pattern it scans incrementally and stays unnoticeable on a live server.
SET with EX so the write and the TTL are one atomic step
SET user:1 "{\"name\":\"tom\"}" EX 300A SET followed by a separate EXPIRE is two commands: a crash in between leaves a key that never expires. Folding EX into SET is atomic. Whether that prevents a thundering herd depends on your code having a fallback branch when GET returns nil.
Reconciling cache against the database
redis-cli --scan --pattern "user:*"
redis-cli -h 127.0.0.1 -p 6379 GET user:1
redis-cli TTL user:1
redis-cli DBSIZEWhen a list page is missing a row, check DBSIZE and TTL first: many -1 values or mass expiry means the whole cache expired, whereas a few stragglers point at an overwrite. TTL -1 means "no expiry", which usually means one write path forgot to set it.
Diagnosing memory and slow queries
INFO memory
MEMORY USAGE user:1
CONFIG GET maxmemory
CONFIG GET maxmemory-policy
SLOWLOG GET 10
SLOWLOG RESETWhen memory climbs, start with mem_fragmentation_ratio and maxmemory-policy: with noeviction, writes are refused rather than evicting anything. Confirm the SLOWLOG threshold via slowlog-log-slower-than — at 0 the log is useless, at -1 it is disabled, and a 0 threshold would also slow the instance down.
Finding blocked connections and deleting large keys
INFO clients
CLIENT LIST
CLIENT KILL ID <id>
MEMORY USAGE bigkey
UNLINK bigkeyDEL on a large collection frees the memory synchronously and occupies the main thread the whole time; UNLINK unlinks the key first and reclaims in the background, so it returns immediately. Blocking commands such as BRPOP also show up in blocked_clients — check it first when client count explodes.
Common Pitfalls
- KEYS walks the entire keyspace and blocks the main thread; on a large instance a single KEYS * is enough to time out every write. Use redis-cli --scan --pattern and work in batches.
- Cache and database have no built-in consistency: crashing after SET, or two instances writing the same key, leaves them diverging with no alert. Paths that must stay consistent should delete the cache key after committing the database write, not populate the cache first.
- RENAME renames in place and silently overwrites an existing destination, copying no data and checking no conflict. Confirm the target key does not exist first, or one rename is one silent data loss.
- AOF defaults to appendfsync everysec, so a failure can lose roughly the last second of writes. Treating that as durability guarantees losing just-placed orders; shorten the fsync interval or accept the window explicitly.
- redis-cli -a password leaves the password in shell history and in the process list. Prefer ACL plus requirepass configuration, and make sure a one-shot -a in a script never lands in CI logs.
- With maxmemory-policy set to noeviction, a full memory limit rejects writes outright. It surfaces as broad application errors rather than slowness, which is easily misdiagnosed as a database or network fault — check CONFIG GET first.
Tips
- Never use KEYS * in production — use SCAN instead. KEYS blocks the main thread and causes stuttering.
- Use UNLINK instead of DEL for large keys (lists/hashes/sets) — DEL blocks the main thread.
- mem_fragmentation_ratio > 1.5 indicates high fragmentation — consider restarting or enabling activedefrag.
FAQ
What is the difference between Redis and Memcached, and when should I use Redis?
Redis supports multiple data structures (strings, hashes, lists, sets, sorted sets) with built-in persistence, while Memcached is simple key-value and pure memory. Choose Redis when you need complex data operations, persistence, leaderboards, message queues, or session storage.
Why should I avoid the KEYS * command in production?
KEYS * traverses the entire keyspace and blocks the Redis main thread; with large datasets it causes stalls and timeouts. Use SCAN instead, which iterates keys incrementally without blocking.
Can Redis lose data? How do I ensure persistence?
Redis offers RDB (point-in-time snapshots) and AOF (append-only log) persistence. RDB restores fast but may lose data after the last snapshot; AOF is safer but larger. Production usually enables both to balance performance and safety.
Official References
Each command links to its official documentation below, so you can verify the latest usage and read deeper.
Maintained by LaoHand
Publicly updated on Jul 21, 2026, continuously proofread against official docs.
Contact Us
Wrong command or description? Send us corrections, business inquiries or product feedback by email.
Contact Us