Vibe Engines
YouTube

Vibe Engines is free, interactive AI engineering & system design — runs in your browser. Pick a learning path

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 6379 is the default); -n 2 selects 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.pem for a private CA
redis-cli PING
run one command and exit; PONG means 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-history samples over time
redis-cli -c
cluster mode: follow MOVED redirects 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 KEYS in 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 DEL blocks
EXPIRE k 30
set a TTL in seconds (PEXPIRE for ms); PERSIST k removes it
TTL k
seconds left; -1 = no expiry, -2 = the key does not exist
RENAME a b
rename a key, overwriting b; RENAMENX refuses if b exists
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 k reads 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; INCRBYFLOAT for 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 name reads one
HGETALL u:1
every field and value — fine for small hashes, use HSCAN for 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; 0 waits 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 tags lists all, SISMEMBER tags a checks one
SINTER · SUNION · SDIFF
intersection · union · difference; the …STORE variants save the result
SCARD · SRANDMEMBER
count members · pick random ones without removing them (SPOP removes)
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; ZREVRANK ranks highest first
ZRANGE k 1 9 BYSCORE
members with scores from 1 to 9 (6.2+); (1 makes 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 v caps the stream
XRANGE s - +
read all entries; XREVRANGE s + - COUNT 10 reads the newest 10
XGROUP CREATE s g $
consumer group starting at new messages; 0 instead of $ replays from the start
XREADGROUP GROUP g c1
COUNT 10 STREAMS s > reads new messages for consumer c1; XACK each 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: EXEC aborts and returns nil if k changed after WATCH
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; INFO alone dumps every section
CLIENT LIST
connected clients with address, idle time and last command; CLIENT KILL drops 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; --memkeys ranks 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 SET changes them at runtime
LATENCY DOCTOR
plain-English analysis of latency spikes (needs latency-monitor-threshold set)
FLUSHDB · FLUSHALL
wipe this database · every database (danger); ASYNC frees memory in the background

Recipes

A fixed-window rate limiter

MULTI
INCR rl:user42:202610221405
EXPIRE rl:user42:202610221405 60
EXEC

The 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 bob

Score 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-7

NX 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.