redis-cli Quick Reference
The commands and data-structure verbs you use against Redis — strings, hashes, lists, sets, sorted sets, and TTLs.
Redis is an in-memory data-structure server. Every key holds one typed value (a string, hash, list, set, sorted set or stream) and each type has its own verbs, so you pick the structure that turns your operation into a single command. Commands execute one at a time on the main thread, which makes each one atomic, but it also means a slow command such as KEYS * or a huge DEL stalls every client. Keys can carry a TTL, and when memory fills, the eviction policy decides what goes.
Command names are case-insensitive; key names are not.
Connect
- redis-cli -h host
- connect (port
-p 6379is the default);-n 2selects database 2 - redis-cli -u redis://…
- connect with a URL:
redis://user:pass@host:6379/0;rediss://uses TLS - REDISCLI_AUTH
- env var for the password — keeps it out of shell history and
ps, unlike-a - redis-cli --tls
- connect over TLS; add
--cacert ca.pemfor a private CA - redis-cli PING
- run one command and exit;
PONGmeans reachable and authenticated - redis-cli -r 10 -i 1
- repeat the command that follows 10 times, 1 second apart — quick monitoring
- redis-cli --stat
- rolling one-line stats: keys, memory, clients, requests
- redis-cli --latency
- measure round-trip latency to the server;
--latency-historysamples over time - redis-cli -c
- cluster mode: follow
MOVEDredirects to the node that owns the key - redis-cli --raw
- print values without quotes or escaping — for piping into other tools
Keys & expiry
- SCAN 0 MATCH user:*
- iterate keys in batches, repeating with the returned cursor until it is 0. Never
KEYSin prod - redis-cli --scan
- the shell version:
--scan --pattern "user:*"prints matching keys, one per line - EXISTS · DEL · TYPE
- does it exist · delete · which data type it holds
- UNLINK k
- delete in a background thread — use it for big keys, where
DELblocks - EXPIRE k 30
- set a TTL in seconds (
PEXPIREfor ms);PERSIST kremoves it - TTL k
- seconds left;
-1= no expiry,-2= the key does not exist - RENAME a b
- rename a key, overwriting
b;RENAMENXrefuses ifbexists - DBSIZE
- number of keys in the current database — instant, unlike counting with SCAN
- OBJECT ENCODING k
- internal encoding (
listpack,hashtable,int…) — explains memory surprises
Strings & counters
- SET k v EX 60
- set with a 60-second TTL;
GET kreads it - SET lock 1 NX EX 30
- set only if absent, with an expiry — the basic distributed lock
- INCR · INCRBY n 5
- atomic counter that starts from 0;
INCRBYFLOATfor decimals - MSET · MGET
- set or read many keys in one round trip
- GETDEL · GETEX
- read and delete · read and change the TTL, atomically (6.2+)
Hashes & lists
- HSET u:1 name Al age 30
- set fields on a hash (one object per key);
HGET u:1 namereads one - HGETALL u:1
- every field and value — fine for small hashes, use
HSCANfor big ones - HINCRBY u:1 visits 1
- atomic counter inside a hash field
- HDEL · HEXISTS · HLEN
- remove a field · check one exists · count fields
- LPUSH q job · RPOP q
- push on the left, pop from the right — a FIFO queue
- LRANGE q 0 -1
- read the whole list; negative indexes count from the end
- BLPOP q 5
- block up to 5 s for an item — a worker’s wait loop;
0waits forever - LTRIM log 0 99
- keep only the newest 100 after each
LPUSH— a capped list - LMOVE a b LEFT RIGHT
- atomically move an item between lists — a reliable queue’s in-progress list (6.2+)
Sets & sorted sets
- SADD tags a b
- add members;
SMEMBERS tagslists all,SISMEMBER tags achecks one - SINTER · SUNION · SDIFF
- intersection · union · difference; the
…STOREvariants save the result - SCARD · SRANDMEMBER
- count members · pick random ones without removing them (
SPOPremoves) - ZADD board 100 alice
- add a member or update its score — a leaderboard
- ZRANGE board 0 9 REV
- top 10 by score, add
WITHSCORES(6.2+); older servers:ZREVRANGE board 0 9 - ZINCRBY board 5 alice
- add to a member’s score atomically
- ZRANK · ZSCORE
- 0-based position, lowest score first · a member’s score;
ZREVRANKranks highest first - ZRANGE k 1 9 BYSCORE
- members with scores from 1 to 9 (6.2+);
(1makes a bound exclusive - ZREMRANGEBYSCORE
- drop members below a score — e.g. timestamps older than a sliding window
- ZPOPMIN · BZPOPMIN
- take the lowest-score member — a priority queue; the B version blocks
- PFADD · PFCOUNT
- HyperLogLog: count unique items in 12 KB with about 0.81% error
Streams & pub/sub
- XADD s * f v
- append an event with an auto ID;
XADD s MAXLEN ~ 1000 * f vcaps the stream - XRANGE s - +
- read all entries;
XREVRANGE s + - COUNT 10reads the newest 10 - XGROUP CREATE s g $
- consumer group starting at new messages;
0instead of$replays from the start - XREADGROUP GROUP g c1
COUNT 10 STREAMS s >reads new messages for consumer c1;XACKeach when done- XPENDING s g
- delivered but unacknowledged messages — stuck consumers show up here
- PUBLISH · SUBSCRIBE
- fire-and-forget messaging: a subscriber that is offline at send time never sees it
Transactions & scripts
- MULTI … EXEC
- queue commands and run them as one atomic block; there is no rollback if one fails
- WATCH k
- optimistic lock:
EXECaborts and returns nil ifkchanged afterWATCH - EVAL "…" 1 key arg
- run a Lua script atomically; declare every key it touches so clusters can route it
Ops & debug
- INFO memory
used_memory_human, peak and fragmentation;INFOalone dumps every section- CLIENT LIST
- connected clients with address, idle time and last command;
CLIENT KILLdrops one - SLOWLOG GET 10
- the 10 latest commands over the slowlog threshold (10 ms by default)
- MEMORY USAGE k
- bytes a key and its value take, overhead included
- redis-cli --bigkeys
- sample the keyspace for the largest key of each type;
--memkeysranks by bytes - MONITOR
- print every command the server receives — dev only, it slows a busy server
- CONFIG GET maxmemory*
- memory limit and eviction policy;
CONFIG SETchanges them at runtime - LATENCY DOCTOR
- plain-English analysis of latency spikes (needs
latency-monitor-thresholdset) - FLUSHDB · FLUSHALL
- wipe this database · every database (danger);
ASYNCfrees memory in the background
Recipes
A fixed-window rate limiter
MULTI
INCR rl:user42:202610221405
EXPIRE rl:user42:202610221405 60
EXECThe key names the user and the current minute, so each window starts fresh and expires on its own; reject the request once the INCR result passes your limit.
Delete keys by pattern without blocking the server
redis-cli --scan --pattern 'session:*' | head
redis-cli --scan --pattern 'session:*' | xargs -n 100 redis-cli UNLINK--scan walks the keyspace incrementally instead of the blocking KEYS, and UNLINK frees memory in a background thread. Check the pattern with the first line before deleting.
A leaderboard with a sorted set
ZADD board 1200 alice 950 bob 1430 cara
ZINCRBY board 50 bob
ZRANGE board 0 2 REV WITHSCORES
ZREVRANK board bobScore updates cost O(log n) and ranks come straight from the index, so top-N stays fast at millions of members. ZREVRANK is 0-based: 0 is first place.
A lock that only its owner can release
SET lock:report worker-7 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:report worker-7NX EX takes the lock only if it is free and lets it expire if the holder dies; the Lua release deletes it only when you still own it, so a slow worker cannot free someone else’s lock.
Find what is using memory
redis-cli INFO memory
redis-cli --bigkeys
redis-cli --memkeys
redis-cli MEMORY USAGE cache:homepage
redis-cli CONFIG GET maxmemory-policy--bigkeys and --memkeys sample with SCAN, so they are safe on a live server. A noeviction policy means writes start failing once memory is full.
Questions about redis-cli Cheat Sheet
Why should I not use KEYS in production Redis?
KEYS walks the entire keyspace in one call, and because Redis executes commands one at a time, every other client waits until it finishes. On a database with millions of keys that can stall the server for seconds, long enough to trip client timeouts and failovers. SCAN does the same job incrementally: each call returns a cursor and a small batch, and you repeat until the cursor comes back as 0. It can return a key more than once, and keys changed during the scan may be missed, so make the processing idempotent.
What happens when Redis runs out of memory?
It depends on the maxmemory-policy setting. With noeviction, the default for a self-managed Redis, commands that need more memory fail with an OOM error while reads keep working. The allkeys-lru and allkeys-lfu policies evict the least recently or least frequently used keys from the whole keyspace, which suits a pure cache. The volatile policies evict only keys that have a TTL, protecting the rest. Set maxmemory explicitly, because 0 means no limit on 64-bit systems, and then the operating system’s OOM killer decides instead.
Is Redis single-threaded?
Command execution is: one main thread runs commands one at a time, which is why each individual command is atomic and the server needs no locks around data. Since Redis 6, optional I/O threads can handle reading from and writing to client sockets, and background threads take care of work such as UNLINK, lazy freeing and file syncing. The practical consequence has not changed. One slow command, such as KEYS on a big keyspace or SMEMBERS on a huge set, delays every other client, so throughput comes from many fast commands.
How do I see what Redis is doing right now?
Start with redis-cli --stat for a rolling line of keys, memory, clients and requests, and INFO for the full picture by section. SLOWLOG GET lists recent commands that exceeded the slow threshold, which is usually where latency problems come from, and CLIENT LIST shows who is connected and what each client ran last. MONITOR prints every command in real time, but it can cut a busy server’s throughput by more than half, so use it briefly and only when the other tools have not explained the problem.