Skip to main content

Redis Cheatsheet — 80+ Commands with Real Pitfalls (Strings, Hashes, Lists, Sets, Sorted Sets, Streams, Pub/Sub)

Redis cheat sheet — 80+ commands across strings, hashes, lists, sets, sorted sets, pub/sub, streams, scripts, with examples and pitfalls.

  • Runs locally
  • Category Developer & DevOps
  • Best for Checking file type, size, metadata, and obvious mismatch signals before sharing.
152 commands
Keys (18)
GET key

Fetch the string value stored at a key. Returns nil if the key does not exist. The single most-used Redis command — every cache read goes through this.

Examples
GET user:1001:name
GET session:abc123
GET feature_flag:dark_mode
SET key value [EX seconds] [NX|XX]

Store a string value at a key, optionally with a TTL. EX sets seconds-based expire, NX only sets if absent (atomic create), XX only sets if present (atomic update).

Common pitfall: Plain SET without EX wipes any previous TTL on the key — the new value lives forever. If you mean "refresh cache, keep TTL", use SET key val KEEPTTL (6.0+) or EXPIRE separately.

Examples
SET user:1001:name "Alice"
SET lock:order:42 worker-7 EX 30 NX
SET cfg:rate_limit 100 XX
DEL key [key ...]

Delete one or more keys. Returns the count of keys actually removed. Synchronous — large keys (a hash with millions of fields) block the event loop while freeing memory.

Common pitfall: For huge keys, use UNLINK instead — it removes the key from the keyspace synchronously but reclaims memory in a background thread.

Examples
DEL user:1001:cache
DEL k1 k2 k3
UNLINK big_hash  -- 大 key 推荐
EXISTS key [key ...]

Check whether one or more keys exist. With N keys, returns the count of existing ones (the same key listed twice counts twice).

Examples
EXISTS user:1001
EXISTS k1 k2 k3
EXISTS missing  -- 返回 0
EXPIRE key seconds

Set a time-to-live in seconds on a key. After the timer fires the key is deleted lazily — on the next access, or by the background purge job.

Common pitfall: EXPIRE on a non-existent key returns 0 silently — there is no error. Always check the return value when setting locks.

Examples
EXPIRE session:abc 3600
EXPIRE cache:home_page 60
PEXPIRE k 500  -- 毫秒
TTL key

Get remaining seconds until a key expires. Returns -2 if the key does not exist, -1 if it exists but has no expire set.

Examples
TTL session:abc  -- 比如返回 1800
TTL forever_key  -- 返回 -1
PTTL k  -- 毫秒
PERSIST key

Remove the TTL from a key, making it persistent. Returns 0 if the key has no expire or does not exist, 1 otherwise.

Examples
PERSIST hot_session
PERSIST upgraded_cache_key
KEYS pattern

Match every key in the database against a glob pattern (e.g. user:*). Walks the entire keyspace in one synchronous shot — never run this in production.

Common pitfall: On a 10M-key database, KEYS * blocks the server for seconds and freezes every other client. Use SCAN. The only safe use of KEYS is on a local dev instance.

Examples
KEYS user:*  -- 仅限本地
KEYS session:*
KEYS *:tmp
SCAN cursor [MATCH pattern] [COUNT n]

Cursor-based incremental keyspace scan — Redis-safe replacement for KEYS. Walks a few buckets at a time, returning a new cursor for the next call. Done when cursor returns 0.

Common pitfall: SCAN may return the same key twice across iterations, and may return keys created/modified during the scan but not guaranteed to. Dedupe in the client. COUNT is a hint, not a limit.

Examples
SCAN 0 MATCH user:* COUNT 1000
SCAN 12345 MATCH session:*
while true; do cursor=$(redis-cli SCAN $cursor MATCH 'tmp:*' | head -1); ...; done
TYPE key

Return the data type of the value stored at a key: string, list, set, zset, hash, stream, or none if the key does not exist.

Examples
TYPE user:1001  -- hash
TYPE leaderboard  -- zset
TYPE missing  -- none
RENAME key newkey

Atomically rename a key. If newkey already exists, it is silently overwritten. Use RENAMENX if you want it to fail when the target exists.

Common pitfall: In Cluster mode, RENAME requires both keys to live on the same hash slot — use {tag} to force colocation: RENAME {usr}:1001 {usr}:1001:archived.

Examples
RENAME old_key new_key
RENAMENX draft:42 published:42
UNLINK key [key ...]

Delete keys like DEL, but reclaim memory in a background thread instead of synchronously. The de-facto safe delete for any key that might be large.

Common pitfall: Background freeing only kicks in past a size threshold — tiny keys are still freed inline, so UNLINK on a small key is no faster than DEL. The win is purely on big keys.

Examples
UNLINK big_hash
UNLINK session:* 的批量 -- 配合 SCAN 拿到 key 再 UNLINK
COPY source destination [DB n] [REPLACE]

Copy the value at source to destination (6.2+). REPLACE overwrites an existing destination; DB targets another database. Preserves the source TTL on the copy.

Examples
COPY user:1001 user:1001:backup
COPY cfg cfg:staging DB 1 REPLACE
DUMP key

Serialize the value at key into a Redis-specific binary blob, which RESTORE can rebuild elsewhere. The pair behind cross-instance key migration tools.

Common pitfall: The blob is NOT portable across major Redis versions in general — RESTORE checks an embedded version/CRC and rejects mismatches. Migrate between matching versions or use RESTORE-friendly tooling.

Examples
DUMP user:1001
RESTORE user:1001:copy 0 "$serialized"  -- 0 表示无 TTL
RANDOMKEY

Return a random key from the current database, or nil if the database is empty. Sampling helper for spot-checking key shapes or estimating TTL coverage.

Examples
RANDOMKEY
for i in {1..100}; do redis-cli RANDOMKEY; done | sort | uniq -c  -- 采样看前缀分布
OBJECT ENCODING key

Reveal the internal encoding Redis chose for a value: listpack, intset, hashtable, skiplist, embstr, int, and so on. The first stop when a key uses more memory than expected.

Common pitfall: Small collections start as compact listpack/intset and silently switch to hashtable/skiplist once they cross hash-max-listpack-entries etc. The switch is one-way and roughly doubles per-element overhead.

Examples
OBJECT ENCODING leaderboard  -- listpack 或 skiplist
OBJECT ENCODING counter  -- int
OBJECT IDLETIME key

Return how many seconds a key has gone untouched (only valid under an LRU maxmemory-policy). Useful for hunting stale keys before a manual cleanup.

Examples
OBJECT IDLETIME old_cache  -- 比如 86400 表示一天没碰
OBJECT FREQ hot_key  -- LFU 策略下看访问频度
MOVE key db

Move a key from the current database to another numbered DB on the same instance. No-op (returns 0) if the destination already has that key.

Common pitfall: Numbered databases do not exist in Redis Cluster, so MOVE errors there. Multi-DB is also discouraged in general — prefer key prefixes or separate instances for isolation.

Examples
MOVE session:abc 1
SELECT 1  -- 切到 1 号库验证
Strings (14)
INCR key

Atomically increment the integer stored at key by 1. If the key does not exist, treats it as 0 first. Returns the new value. Foundation of counters and rate limiters.

Common pitfall: Fails with an error if the value is not parseable as an int64. Bumping a value of "abc" or 9999999999999999999 throws — wrap counter keys with a clear naming convention.

Examples
INCR page_views:home
INCR rate_limit:ip:1.2.3.4
INCRBY user:42:credits 10
DECR key

Atomically decrement the integer stored at key by 1. Useful for releasing seats in a fixed-size resource pool.

Examples
DECR inventory:sku:42
DECRBY queue_depth 5
APPEND key value

Append a string to the value at key. If the key does not exist, behaves like SET. Returns the new total length.

Examples
APPEND log:2026-05-26 "request_id=42\n"
APPEND buffer:user:1 chunk
GETSET key value

Atomically set a new value and return the old one. Common pattern for resetting a counter and reading its previous total in a single round-trip.

Common pitfall: Deprecated since 6.2 in favor of SET key value GET — same semantics, more consistent option flags. Both still work.

Examples
GETSET page_views:home 0
SET counter 0 GET  -- 推荐写法
STRLEN key

Return the byte length of the string at key. Returns 0 if the key does not exist. Useful for quick "is the cache populated?" probes.

Examples
STRLEN session:abc  -- 比如返回 312
STRLEN empty_key  -- 0
SETEX key seconds value

Set key with a value and a TTL in seconds in one atomic command. Equivalent to SET key value EX seconds but two commands shorter.

Examples
SETEX session:abc 3600 user_id=42
SETEX cache:home 60 "<html>..."
SETNX key value

Set key only if it does not already exist. Returns 1 on success, 0 if the key was present. Classic primitive for "first writer wins" patterns.

Common pitfall: Modern code should prefer SET key value NX EX ttl — SETNX has no TTL option, so a separate EXPIRE leaves a window where the key is permanent if the client crashes between commands.

Examples
SETNX lock:order:42 worker-7
SET lock:order:42 worker-7 NX EX 30  -- 推荐
MSET key value [key value ...]

Set multiple keys to multiple values in one atomic round-trip. Either every key is set or (it cannot fail mid-way) none — there is no partial MSET.

Examples
MSET user:1:name Alice user:1:age 30
MSETNX a 1 b 2  -- 全部不存在才设,原子
MGET key [key ...]

Fetch multiple string values in one round-trip, returning an array aligned to the input order. Missing keys come back as nil in their slot.

Common pitfall: In Cluster mode all keys must live on the same hash slot, or MGET errors with CROSSSLOT. Use {tag} to colocate, or fan out per-slot client-side.

Examples
MGET user:1:name user:2:name user:3:name
MGET {usr}:1 {usr}:2  -- 集群下用 hash tag 同槽
INCRBYFLOAT key increment

Increment the value at key by a floating-point amount, returning the new value as a string. Handles money-style fractional math without a separate float type.

Common pitfall: Floating-point rounding still applies — 0.1 + 0.2 will not be exactly 0.3. For currency, store integer cents and INCRBY, not INCRBYFLOAT on dollars.

Examples
INCRBYFLOAT account:42:balance 0.99
INCRBYFLOAT sensor:temp -1.5
SETRANGE key offset value

Overwrite part of the string at key starting at a byte offset, zero-padding if the offset is past the current end. Treats a string as a fixed-layout byte buffer.

Examples
SETRANGE packet:42 4 "PAYLOAD"
SETRANGE greeting 6 "Redis"  -- 改第 6 字节起的内容
GETRANGE key start end

Return a substring of the string at key by inclusive byte range; negative indexes count from the tail (-1 = last byte). The read counterpart to SETRANGE.

Examples
GETRANGE log_line 0 99  -- 前 100 字节
GETRANGE iso_date 0 3  -- 取年份 "2026"
GETDEL key

Atomically read the value at key and delete it in one step (6.2+). The clean primitive for one-shot tokens — read it, and it is gone.

Examples
GETDEL otp:user:42  -- 一次性验证码
GETDEL pending_payload:abc
GETEX key [EX seconds | PERSIST]

Read the value at key and adjust its TTL in the same command (6.2+): EX refreshes the expire, PERSIST strips it. Sliding-window sessions without a second round-trip.

Examples
GETEX session:abc EX 1800  -- 读会话并续 30 分钟
GETEX cache:home PERSIST  -- 读并转永久
Hashes (13)
HSET key field value [field value ...]

Set one or more fields on a hash. Returns the count of NEW fields added (overwrites do not count). Hashes are the right shape for "object with a few small fields".

Common pitfall: HSET key f v (older HMSET) was deprecated in 4.0 — HSET now accepts multiple field-value pairs. HMSET still works but should not be used in new code.

Examples
HSET user:1001 name Alice age 30 email alice@x.io
HSET cart:42 sku:1 2 sku:2 1
HGET key field

Get the value of one field on a hash. Returns nil if the field or the key does not exist.

Examples
HGET user:1001 name  -- "Alice"
HGET cfg dark_mode
HMGET key field [field ...]

Get multiple field values from a hash in one round-trip. Returns an array with nil for any missing fields, preserving input order.

Examples
HMGET user:1001 name age email
HMGET cfg theme lang tz
HDEL key field [field ...]

Delete one or more fields from a hash. Returns the count actually removed. When the last field is deleted, the hash itself is removed.

Examples
HDEL user:1001 stale_flag
HDEL cart:42 sku:1 sku:3
HKEYS key

Return every field name in a hash, in arbitrary order. O(N) over the hash size — fine for objects with dozens of fields, dangerous for millions.

Examples
HKEYS user:1001
HKEYS cfg
HVALS key

Return every value in a hash, in arbitrary order. Same complexity as HKEYS — use HSCAN for large hashes.

Examples
HVALS cfg
HVALS leaderboard_summary
HGETALL key

Return every field AND value in a hash as a flat [f1, v1, f2, v2, ...] array. Convenient but dangerous on large hashes.

Common pitfall: HGETALL on a hash with 100k+ fields can return MBs of data in one reply, blocking the event loop and using huge client-side memory. Switch to HSCAN or partition the hash.

Examples
HGETALL user:1001
HSCAN big_hash 0 COUNT 500  -- 安全替代
HINCRBY key field increment

Atomically increment an integer field on a hash. Auto-creates the field at 0 if absent. Foundation of per-user counter aggregates.

Examples
HINCRBY user:1001:stats login_count 1
HINCRBY user:1001:stats bytes_uploaded 4096
HINCRBYFLOAT user:1001:wallet usd 0.99
HSETNX key field value

Set a hash field only if it does not already exist. Returns 1 if the field was created, 0 if it was already there. Per-field "first writer wins".

Examples
HSETNX user:1001 created_at 1716700000
HSETNX cfg first_seen_version 5
HEXISTS key field

Check whether a single field exists in a hash. O(1). Returns 1 if present, 0 if the field or the whole hash is missing.

Examples
HEXISTS user:1001 email
HEXISTS cfg dark_mode  -- 0 表示未设置过
HLEN key

Return the number of fields in a hash. O(1) — the count lives in the hash header. Returns 0 for a missing key.

Examples
HLEN user:1001  -- 比如 5 个字段
HLEN cart:42  -- 购物车 SKU 数
HSCAN key cursor [MATCH pattern] [COUNT n] [NOVALUES]

Cursor-based incremental scan over a hash, the safe alternative to HGETALL on big hashes. NOVALUES (7.4+) returns field names only, halving the payload.

Common pitfall: Like SCAN, HSCAN can return the same field more than once across iterations and COUNT is only a hint. Treat fields as a set on the client side.

Examples
HSCAN big_hash 0 MATCH attr:* COUNT 500
HSCAN user:1001 0 NOVALUES  -- 只要字段名(7.4+)
HRANDFIELD key [count [WITHVALUES]]

Return random field(s) from a hash (6.2+). A positive count returns distinct fields; a negative count allows repeats. WITHVALUES pairs each with its value.

Examples
HRANDFIELD user:1001  -- 随机一个字段
HRANDFIELD quiz_bank 3 WITHVALUES  -- 随机抽 3 道题
Lists (15)
LPUSH key value [value ...]

Push one or more values onto the HEAD (left) of a list. Auto-creates the list if missing. Returns the new length. Pair with RPOP for FIFO queues.

Examples
LPUSH queue:jobs job_42
LPUSH queue:jobs job_43 job_44  -- 多值
LPUSH log:errors "$timestamp $msg"
RPUSH key value [value ...]

Push values onto the TAIL (right) of a list. Pair with LPOP for FIFO; pair with RPOP for LIFO. Single command runs at sub-millisecond cost.

Examples
RPUSH queue:jobs job_42
RPUSH timeline:1001 "post:42"
LPOP key [count]

Pop and return one value from the HEAD of a list. With count (6.2+) returns up to N values at once. Returns nil on an empty/missing list.

Examples
LPOP queue:jobs
LPOP queue:jobs 10  -- 一次取一批
RPOP key [count]

Pop and return one value from the TAIL of a list. Same shape as LPOP. With count, returns up to N entries.

Examples
RPOP queue:jobs
RPOP queue:jobs 100
LRANGE key start stop

Return a slice of a list by index. Indexes are inclusive on both ends; negative indexes count from the tail (-1 = last). LRANGE k 0 -1 is the entire list.

Common pitfall: LRANGE k 0 -1 on a list with millions of items is O(N) and ships the entire list to the client. Always paginate (LRANGE k 0 99, then 100 199, ...).

Examples
LRANGE timeline 0 9  -- 前 10 条
LRANGE timeline -10 -1  -- 最后 10 条
LLEN key

Return the length of a list. O(1) — Redis maintains the count in the list header. Returns 0 if the key does not exist.

Examples
LLEN queue:jobs  -- 比如 42
LLEN missing  -- 0
LINDEX key index

Get the element at a specific index in a list. Negative indexes count from the tail. O(N) on long lists — avoid in hot paths.

Examples
LINDEX timeline 0  -- 第一条
LINDEX timeline -1  -- 最后一条
LREM key count value

Remove up to |count| occurrences of value from a list. count > 0 starts from head, < 0 starts from tail, 0 removes ALL matches. Returns the number actually removed.

Examples
LREM dedupe_queue 1 job_42  -- 从头删第一个
LREM dedupe_queue 0 job_42  -- 全删
BLPOP key [key ...] timeout

Blocking left-pop: wait up to timeout seconds (0 = forever) for an element on any of the given lists. Returns [key, value] when ready, nil on timeout.

Common pitfall: In Cluster mode all keys must hash to the same slot, so use {tag}. Each blocked client holds a connection — if you have 10k workers, plan for 10k open sockets on the Redis side.

Examples
BLPOP queue:jobs 5
BLPOP queue:high queue:low 0  -- 优先级队列
LSET key index value

Overwrite the element at a given list index with a new value. Errors if the index is out of range. Negative indexes count from the tail.

Examples
LSET timeline 0 "post:99"  -- 改最新一条
LSET queue -1 "retry:job_42"  -- 改最后一个
LTRIM key start stop

Trim a list to only the elements within the inclusive index range, discarding everything else. The standard way to keep a capped "latest N" feed.

Common pitfall: LPUSH then LTRIM is the canonical capped-list pattern, but run them in a MULTI or a Lua script — between the two commands the list briefly exceeds the cap and a concurrent reader sees extra items.

Examples
LPUSH feed:1001 "post:99"
LTRIM feed:1001 0 99  -- 只留最新 100 条
LTRIM log 0 -1  -- 不变(保留全部)
LINSERT key BEFORE|AFTER pivot value

Insert a value just before or after the first occurrence of a pivot element. Returns the new length, -1 if the pivot was not found, 0 if the key is missing.

Common pitfall: LINSERT scans from the head to find the pivot — O(N). On long lists this is slow, and it only ever touches the FIRST match, not all of them.

Examples
LINSERT playlist BEFORE "song:5" "song:ad"
LINSERT steps AFTER "build" "test"
RPOPLPUSH source destination

Atomically pop from the tail of source and push onto the head of destination, returning the moved element. The classic reliable-queue building block.

Common pitfall: Deprecated since 6.2 in favor of LMOVE, which lets you choose either end on both sides. Pattern: RPOPLPUSH queue processing, then remove from processing only after the work succeeds.

Examples
RPOPLPUSH queue processing
LMOVE queue processing LEFT RIGHT  -- 推荐(6.2+)
BRPOPLPUSH source destination timeout

Blocking version of RPOPLPUSH: wait up to timeout seconds for an element on source, then atomically move it to destination. Powers reliable worker queues.

Common pitfall: Deprecated since 6.2 — use BLMOVE. The reliable-queue idea: workers BLMOVE jobs→inflight, process, then LREM from inflight; a periodic reaper requeues anything stuck in inflight too long.

Examples
BRPOPLPUSH jobs inflight 5
BLMOVE jobs inflight LEFT RIGHT 5  -- 推荐(6.2+)
BRPOP key [key ...] timeout

Blocking right-pop: wait up to timeout seconds (0 = forever) for an element on the tail of any listed list. Returns [key, value] or nil on timeout.

Examples
BRPOP queue:jobs 5
BRPOP queue:high queue:low 0  -- 配 RPUSH 做 FIFO 优先级队列
Sets (13)
SADD key member [member ...]

Add one or more members to a set. Returns the count of NEW members (duplicates are silently ignored). Sets give O(1) membership tests.

Examples
SADD online_users 1001 1002 1003
SADD tags:post:42 redis tutorial cache
SREM key member [member ...]

Remove one or more members from a set. Returns the count actually removed. Removing the last member also drops the set itself.

Examples
SREM online_users 1001
SREM tags:post:42 deprecated
SMEMBERS key

Return every member of a set in arbitrary order. O(N) — fine for "tags on a post" (10s of members), dangerous for big sets.

Common pitfall: For large sets, use SSCAN. SMEMBERS on a 1M-member set returns 1M strings in one reply, eating client memory and blocking Redis.

Examples
SMEMBERS tags:post:42
SSCAN big_set 0 COUNT 500  -- 大 set 安全替代
SISMEMBER key member

Test whether a member exists in a set. O(1). Foundation of per-user feature flags, online presence, banned-IP lookups.

Examples
SISMEMBER online_users 1001
SISMEMBER banned_ips 1.2.3.4
SMISMEMBER online_users 1001 1002 1003  -- 批量(6.2+)
SUNION key [key ...]

Return the union of multiple sets — every distinct member appearing in any input. Useful for "users active today OR yesterday" style queries.

Examples
SUNION active:today active:yesterday
SUNIONSTORE active:48h active:today active:yesterday
SINTER key [key ...]

Return the intersection of multiple sets — members present in EVERY input. Common for "users who clicked both ad A AND ad B" style cohort math.

Common pitfall: Complexity is O(N*M) where N is the smallest set and M is the number of sets. Always put the smallest set first — Redis short-circuits when an early miss eliminates a candidate.

Examples
SINTER ad_A_clickers ad_B_clickers
SINTERSTORE both_clickers ad_A_clickers ad_B_clickers
SDIFF key [key ...]

Return members in the first set that are NOT in any of the subsequent sets. The Redis way to compute "everyone who has not yet seen the popup".

Examples
SDIFF all_users popup_seen
SDIFFSTORE retarget all_users popup_seen unsubscribed
SCARD key

Return the number of members in a set. O(1) — the cardinality is tracked in the set header. Returns 0 for a missing key.

Examples
SCARD online_users  -- 当前在线数
SCARD tags:post:42
SPOP key [count]

Remove and return one or more RANDOM members from a set. Unlike SRANDMEMBER, SPOP mutates the set. Common for "draw N winners without replacement".

Examples
SPOP raffle:pool  -- 抽一个并移出
SPOP raffle:pool 3  -- 一次抽 3 个不重复
SRANDMEMBER key [count]

Return random member(s) from a set WITHOUT removing them. A positive count returns distinct members; a negative count allows repeats and may exceed the set size.

Examples
SRANDMEMBER products:featured 4  -- 随机推荐 4 个
SRANDMEMBER dice:faces -10  -- 模拟 10 次有放回掷骰
SMOVE source destination member

Atomically move a member from one set to another. Returns 1 on success, 0 if the member was not in source. Both sets are touched in a single step.

Examples
SMOVE pending approved order:42
SMOVE online away user:1001
SSCAN key cursor [MATCH pattern] [COUNT n]

Cursor-based incremental scan over a set — the safe replacement for SMEMBERS on large sets. Walks a few buckets per call, done when the cursor returns 0.

Examples
SSCAN ip:banned 0 MATCH "10.*" COUNT 500
SSCAN set:huge 0 COUNT 1000
SINTERCARD numkeys key [key ...] [LIMIT n]

Return the size of the intersection of sets WITHOUT materializing it (7.0+). LIMIT short-circuits once the count reaches n — much cheaper than SINTER when you only need "are there at least n in common".

Examples
SINTERCARD 2 ad_A_clickers ad_B_clickers
SINTERCARD 2 followers:1 followers:2 LIMIT 1  -- 只问有无共同关注
Sorted sets (13)
ZADD key [NX|XX] [GT|LT] [CH] score member [score member ...]

Add or update members in a sorted set. NX skips updates, XX skips inserts, GT/LT only update when the new score is greater/less. Returns count of NEW members (or changes if CH).

Examples
ZADD leaderboard 100 alice 95 bob 110 carol
ZADD high_scores GT 200 alice  -- 仅当 200 比当前高才更新
ZADD jobs:scheduled 1716700000 job_42  -- 用时间戳当分数
ZRANGE key start stop [WITHSCORES] [REV] [BYSCORE|BYLEX] [LIMIT offset count]

Range query on a sorted set. Default by rank (lowest score first); REV reverses; BYSCORE switches to score range; BYLEX to lexicographic range. The 6.2+ swiss-army knife.

Examples
ZRANGE leaderboard 0 9 WITHSCORES  -- 前 10
ZRANGE leaderboard 0 9 REV WITHSCORES  -- top 10 倒序
ZRANGE leaderboard 100 200 BYSCORE LIMIT 0 50
ZREVRANGE key start stop [WITHSCORES]

Return members ordered by score from HIGH to LOW. Equivalent to ZRANGE ... REV on 6.2+. Classic "top N leaderboard" call.

Common pitfall: Deprecated since 6.2 — prefer ZRANGE ... REV for new code. Still supported and identical in behavior.

Examples
ZREVRANGE leaderboard 0 9 WITHSCORES
ZRANGE leaderboard 0 9 REV WITHSCORES  -- 推荐
ZRANGEBYSCORE key min max [LIMIT offset count]

Return members whose score falls in [min, max]. Use ( for exclusive bounds. Combined with timestamp scores, this is how you implement "scheduled jobs ready to run".

Examples
ZRANGEBYSCORE jobs:scheduled -inf 1716700000  -- 时间戳之前
ZRANGEBYSCORE leaderboard (100 200  -- (100, 200]
ZRANGEBYSCORE leaderboard 100 +inf LIMIT 0 50
ZINCRBY key increment member

Atomically increment the score of a member in a sorted set. Auto-creates the member with score = increment if absent.

Examples
ZINCRBY leaderboard 10 alice
ZINCRBY trending:topics 1 "redis"
ZRANK key member [WITHSCORE]

Return the 0-based rank of a member, ordered by score ascending. Returns nil if the member does not exist. ZREVRANK for high-to-low rank.

Examples
ZRANK leaderboard alice  -- 比如 5
ZREVRANK leaderboard alice  -- 高到低
ZRANK leaderboard alice WITHSCORE  -- 7.2+
ZSCORE key member

Return the score of a member in a sorted set as a string, or nil if the member is absent. O(1). ZMSCORE (6.2+) fetches several scores at once.

Examples
ZSCORE leaderboard alice  -- 比如 "110"
ZMSCORE leaderboard alice bob carol  -- 批量(6.2+)
ZCARD key

Return the number of members in a sorted set. O(1). Returns 0 for a missing key. Pair with ZCOUNT to count members within a score range.

Examples
ZCARD leaderboard  -- 总参赛人数
ZCOUNT leaderboard 90 100  -- 分数在 [90,100] 的人数
ZREM key member [member ...]

Remove one or more members from a sorted set. Returns the count actually removed. Removing the last member drops the key. Foundation of leaderboard eviction.

Examples
ZREM leaderboard cheater_42
ZREM jobs:scheduled job_done_1 job_done_2
ZPOPMIN key [count]

Atomically remove and return the member(s) with the LOWEST score (5.0+), each paired with its score. The natural pop for a min-score priority queue.

Examples
ZPOPMIN jobs:scheduled  -- 取最早该跑的任务
ZPOPMIN delay_queue 10  -- 一次取 10 个
ZPOPMAX key [count]

Atomically remove and return the member(s) with the HIGHEST score (5.0+), each with its score. BZPOPMIN / BZPOPMAX are the blocking variants for queue workers.

Examples
ZPOPMAX high_scores  -- 取当前最高分并移出
BZPOPMIN delay_queue 5  -- 阻塞取最小分数(5.0+)
ZREMRANGEBYSCORE key min max

Remove every member whose score falls in [min, max]. With timestamp scores this is the one-liner for "purge everything older than cutoff" on a sliding-window set.

Examples
ZREMRANGEBYSCORE rate_limit:ip:1.2.3.4 -inf (1716700000  -- 滑窗限流清旧
ZREMRANGEBYRANK leaderboard 0 -101  -- 只留 top 100
ZRANGESTORE dest src min max [BYSCORE|BYLEX] [REV] [LIMIT off count]

Run a ZRANGE query and store the resulting members (with scores) into a destination sorted set (6.2+). Materialize a "top N" snapshot without round-tripping the data to the client.

Examples
ZRANGESTORE top10 leaderboard 0 9 REV  -- 固化前 10 名
ZUNIONSTORE combined 2 lb:eu lb:us  -- 合并两个榜
Bitmaps (6)
SETBIT key offset value

Set a single bit (0 or 1) at the given byte offset on a string. Auto-extends the string with zero-bytes if the offset is past the end. Use for compact daily-active-user flags.

Common pitfall: SETBIT k 100000000 1 allocates a 12.5 MB string instantly. Watch the offset — a typo with user_id*8 vs user_id can blow memory.

Examples
SETBIT dau:2026-05-26 1001 1
SETBIT feature:beta 42 1
GETBIT key offset

Get the bit (0 or 1) at the given offset on a string. Returns 0 if the offset is past the end of the string.

Examples
GETBIT dau:2026-05-26 1001  -- 1 表示活跃
GETBIT feature:beta 42
BITCOUNT key [start end [BYTE|BIT]]

Count the number of set bits (1s) in a string, optionally within a byte or bit range. The fastest way to ask "how many users were active today?".

Examples
BITCOUNT dau:2026-05-26  -- 当日总活跃数
BITCOUNT dau:2026-05-26 0 999 BYTE
BITOP AND|OR|XOR|NOT destkey key [key ...]

Bitwise op across one or more source strings, storing the result at destkey. Combine daily DAU bitmaps to compute weekly retention, churn, or N-day active cohorts.

Common pitfall: BITOP is O(N) over the longest source string. Daily DAU bitmaps for 10M users are 1.25 MB each — fine, but BITOP across a year of them is over 450 MB written to destkey, every time.

Examples
BITOP AND retention:7d dau:2026-05-20 dau:2026-05-26
BITOP OR active:week dau:2026-05-20 dau:2026-05-21 ... dau:2026-05-26
BITPOS key bit [start [end [BYTE|BIT]]]

Find the position of the first 0 or 1 bit in a string, optionally within a range. Handy for "find the first free slot" allocators backed by a bitmap.

Examples
BITPOS slots 0  -- 第一个空闲槽
BITPOS dau:2026-05-26 1  -- 第一个活跃用户的位
BITFIELD key [GET|SET|INCRBY type offset value] [OVERFLOW WRAP|SAT|FAIL]

Treat a string as an array of arbitrary-width signed/unsigned integers, reading and updating several fields in one atomic command. OVERFLOW controls wrap / saturate / fail on overflow.

Common pitfall: Offsets are in units of the type unless prefixed with #. BITFIELD k SET u8 #0 vs BITFIELD k SET u8 0 mean different things — # multiplies by the type width. Mixing the two corrupts your layout.

Examples
BITFIELD stats INCRBY u8 #0 1 GET u8 #0  -- 第 0 个 u8 加 1 并读回
BITFIELD counter OVERFLOW SAT INCRBY u8 #0 200  -- 饱和到 255 不回绕
HyperLogLog (4)
PFADD key element [element ...]

Add one or more elements to a HyperLogLog. Returns 1 if the estimated cardinality changed, 0 otherwise. Uses a fixed 12 KB regardless of element count.

Common pitfall: HyperLogLog is APPROXIMATE — standard error around 0.81%. Never use it where exact counts matter (billing, audit logs). Perfect for UV / dedupe at billion scale.

Examples
PFADD uv:2026-05-26 user_1001 user_1002
PFADD uniq_search_terms "redis cheat"
PFCOUNT key [key ...]

Return the approximate cardinality of one HyperLogLog, or the merged cardinality of several. Cost is O(1) for one key, O(N) for the merge case.

Examples
PFCOUNT uv:2026-05-26
PFCOUNT uv:2026-05-20 uv:2026-05-21 uv:2026-05-26  -- 多日合并
PFMERGE destkey sourcekey [sourcekey ...]

Merge multiple HyperLogLogs into destkey. Idempotent — re-merging the same sources produces the same destination. Common for "compute monthly UV from daily UVs".

Examples
PFMERGE uv:2026-05 uv:2026-05-01 uv:2026-05-02 ... uv:2026-05-31
PFADD vs Set memory

A HyperLogLog counts unique elements in a fixed ~12 KB no matter how many you add, whereas a Set storing the same members grows linearly. The trade is exactness for constant memory.

Common pitfall: If you ever need the actual members (not just the count), you cannot use a HLL — it is one-way. Keep a real Set only when you must enumerate; use HLL purely for cardinality.

Examples
PFADD uv:2026-05-26 u1 u2 u3
MEMORY USAGE uv:2026-05-26  -- 约 12KB 上限
Pub/Sub (5)
PUBLISH channel message

Broadcast a message to every client SUBSCRIBEd to channel. Returns the number of subscribers that received it. Fire-and-forget — no persistence, no replay.

Common pitfall: A subscriber that is offline when you PUBLISH NEVER gets the message — there is no buffering. For at-least-once delivery, use Streams (XADD + XREADGROUP).

Examples
PUBLISH events:user_signup user_1001
PUBLISH chat:room:42 "hello"
SUBSCRIBE channel [channel ...]

Listen for messages on one or more channels. The connection enters subscribe mode — most regular commands become forbidden until UNSUBSCRIBE.

Examples
SUBSCRIBE events:user_signup
SUBSCRIBE chat:room:42 chat:room:43
PSUBSCRIBE pattern [pattern ...]

Subscribe to every channel matching one or more glob patterns. Each delivered message carries the actual matching channel name plus the matched pattern.

Common pitfall: PSUBSCRIBE chat:* matches every chat:N channel — fine for 10 rooms, painful for 10M. Pattern matching runs on every PUBLISH and is O(patterns * subscribers).

Examples
PSUBSCRIBE chat:*
PSUBSCRIBE events:*
PUBSUB CHANNELS [pattern]

List the active channels that currently have at least one subscriber, optionally filtered by a glob pattern. Introspection for "who is listening to what right now".

Examples
PUBSUB CHANNELS
PUBSUB CHANNELS chat:*
PUBSUB NUMSUB chat:42  -- 某频道订阅者数
SPUBLISH shardchannel message

Publish to a shard channel in Redis Cluster (7.0+). Unlike regular PUBLISH, sharded pub/sub routes by slot and does NOT broadcast across every node, so it scales with the cluster.

Common pitfall: Regular PUBLISH in Cluster fans the message to every node, which does not scale. For high-throughput cluster pub/sub use SPUBLISH + SSUBSCRIBE so traffic stays on the owning shard.

Examples
SPUBLISH orders:shard "new_order"
SSUBSCRIBE orders:shard  -- 分片订阅(7.0+)
Streams (10)
XADD key [MAXLEN [~|=] N] * field value [field value ...]

Append a new entry to a stream. * means "let Redis assign the ID" (ms timestamp + seq). MAXLEN with ~ caps stream length approximately, with = exactly. Streams are the durable, replayable replacement for Pub/Sub.

Common pitfall: Without MAXLEN, streams grow forever and eat memory. Always cap producer streams (MAXLEN ~ 1000000) or trim periodically with XTRIM. The ~ form is much cheaper than =.

Examples
XADD events:orders * user 1001 sku 42 qty 2
XADD events:orders MAXLEN ~ 100000 * user 1001 sku 42
XREAD [COUNT n] [BLOCK ms] STREAMS key [key ...] id [id ...]

Read new entries from one or more streams after the given IDs. $ means "only entries added AFTER I started waiting". BLOCK 0 waits forever.

Examples
XREAD COUNT 100 STREAMS events:orders 0
XREAD BLOCK 5000 STREAMS events:orders $
XREADGROUP GROUP grp consumer [COUNT n] [BLOCK ms] STREAMS key id

Consumer-group read — Redis tracks delivery per consumer for at-least-once semantics. ID = > means "new messages this consumer has not seen". Pair with XACK after processing.

Common pitfall: You MUST create the group first with XGROUP CREATE — XREADGROUP on a non-existent group errors. After a consumer crashes, use XPENDING + XCLAIM to reassign its pending entries.

Examples
XGROUP CREATE events:orders processors $ MKSTREAM
XREADGROUP GROUP processors worker-1 COUNT 100 BLOCK 5000 STREAMS events:orders >
XACK key group id [id ...]

Acknowledge that one or more entries have been processed by the consumer group. Until you XACK, an entry stays in the group's pending list and can be reassigned.

Examples
XACK events:orders processors 1716700000-0
XLEN key

Return the number of entries currently in a stream. O(1). Pair with XINFO STREAM key for full metadata (first/last entry, groups, length).

Examples
XLEN events:orders
XINFO STREAM events:orders
XRANGE key start end [COUNT n]

Return stream entries with IDs in the inclusive range [start, end]. - and + mean the smallest and largest possible IDs, so XRANGE k - + COUNT 10 reads the oldest 10 entries.

Examples
XRANGE events:orders - + COUNT 10  -- 最旧 10 条
XREVRANGE events:orders + - COUNT 10  -- 最新 10 条
XPENDING key group [IDLE ms] [start end count [consumer]]

Inspect entries delivered to a consumer group but not yet XACKed. The summary form shows total pending plus per-consumer counts; the extended form lists individual stuck entries.

Common pitfall: A growing XPENDING count means consumers are crashing or slow — entries pile up forever until claimed. Pair a reaper that XCLAIMs entries idle past a threshold and routes poison messages to a dead-letter stream.

Examples
XPENDING events:orders processors  -- 概览
XPENDING events:orders processors IDLE 60000 - + 100  -- 卡超过 60s 的
XCLAIM key group consumer min-idle-time id [id ...]

Transfer ownership of pending entries that have been idle at least min-idle-time to another consumer. The recovery primitive when a worker dies mid-processing.

Common pitfall: XAUTOCLAIM (6.2+) is usually easier: it scans, claims, and returns a cursor in one call, so you do not have to XPENDING first. Always cap retries — an entry that keeps failing should go to a dead-letter stream.

Examples
XCLAIM events:orders processors worker-2 60000 1716700000-0
XAUTOCLAIM events:orders processors worker-2 60000 0  -- 推荐(6.2+)
XGROUP CREATE key group id [MKSTREAM]

Create a consumer group on a stream, starting from a given ID ($ = only new entries, 0 = from the beginning). MKSTREAM auto-creates the stream if it does not exist yet.

Common pitfall: Without MKSTREAM, XGROUP CREATE on a missing stream errors. Starting at $ means the group ignores every entry that already exists — use 0 if you need to process the backlog too.

Examples
XGROUP CREATE events:orders processors $ MKSTREAM
XGROUP CREATECONSUMER events:orders processors worker-3  -- 显式建消费者
XTRIM key MAXLEN|MINID [~|=] threshold

Trim a stream by length (MAXLEN) or by minimum ID (MINID, 6.2+). The ~ form trims approximately and is far cheaper because it only drops whole macro-nodes.

Examples
XTRIM events:orders MAXLEN ~ 1000000
XTRIM events:orders MINID 1716700000000  -- 丢弃此时间戳前的(6.2+)
Scripts (Lua) (5)
EVAL script numkeys key [key ...] arg [arg ...]

Run an inline Lua script atomically against Redis. All keys must be declared via numkeys + KEYS[]. Scripts are sandboxed and run single-threaded — every keystroke blocks the server.

Common pitfall: Long-running scripts block ALL other clients. Hard limit is lua-time-limit (5s default), after which only SCRIPT KILL or SHUTDOWN NOSAVE can recover. Keep scripts to a handful of commands.

Examples
EVAL "return redis.call('GET', KEYS[1])" 1 mykey
EVAL "local v = redis.call('INCR', KEYS[1]); if v > tonumber(ARGV[1]) then redis.call('DEL', KEYS[1]); return 0 end; return v" 1 rate_limit 100
EVALSHA sha1 numkeys key [key ...] arg [arg ...]

Run a previously cached script by its SHA-1 digest. Cuts the bandwidth from the full script body to 40 hex chars per call. Falls back to EVAL on NOSCRIPT errors.

Examples
EVALSHA a9d8b1c... 1 rate_limit 100
-- 通常配合 SCRIPT LOAD: SHA=$(redis-cli SCRIPT LOAD "$src"); redis-cli EVALSHA $SHA ...
SCRIPT LOAD script

Cache a script on the server and return its SHA-1. The script is NOT executed. Use this to warm caches on startup, then call EVALSHA from then on.

Common pitfall: FLUSHALL or restart wipes the script cache — every client must be ready to re-LOAD on NOSCRIPT. In Redis Cluster, you must LOAD on EVERY shard separately.

Examples
SCRIPT LOAD "return 1"  -- 返回 e0e1f9fabfc9d4800c877a703b823ac0578ff831
FCALL function numkeys key [key ...] arg [arg ...]

Call a named function from a loaded Redis Functions library (7.0+). Functions are the durable successor to EVAL scripts — registered by name, persisted in the RDB/AOF, and replicated.

Common pitfall: Unlike EVAL scripts (which vanish on FLUSHALL / restart), a FUNCTION LOADed library survives restarts and replicates to replicas automatically. Migrate hot EVALSHA paths to FUNCTION for operational sanity.

Examples
FUNCTION LOAD "#!lua name=mylib\nredis.register_function('myfunc', function(keys, args) return redis.call('GET', keys[1]) end)"
FCALL myfunc 1 mykey
SCRIPT EXISTS sha1 [sha1 ...]

Check whether one or more scripts are already cached on the server by SHA-1, returning a 1/0 array. Clients use this to decide between EVALSHA and a re-LOAD.

Examples
SCRIPT EXISTS a9d8b1c...  -- [1] 已缓存
SCRIPT FLUSH  -- 清空整个脚本缓存
Transactions (5)
MULTI

Start a transaction block. Subsequent commands are queued (return QUEUED) rather than executed, until EXEC or DISCARD. MULTI/EXEC blocks run atomically.

Examples
MULTI
INCR a
INCR b
EXEC
EXEC

Execute all commands queued since MULTI atomically, returning an array of replies. If a WATCHed key was modified, returns nil and the whole transaction is aborted.

Common pitfall: Redis transactions are NOT rollback-on-error like SQL. If one command in the block fails (e.g. wrong type), the others STILL EXECUTE. EXEC just returns a per-command result.

Examples
MULTI
SET a 1
SET b 2
EXEC  -- 返回 ["OK", "OK"]
DISCARD

Drop the queued commands and exit MULTI mode without executing. The connection returns to normal command mode.

Examples
MULTI
SET a 1
DISCARD  -- a 不变
WATCH key [key ...]

Optimistic-locking primitive. WATCH some keys, then MULTI/EXEC — if any watched key was modified by anyone between WATCH and EXEC, the transaction aborts. The Redis CAS pattern.

Examples
WATCH balance
val = GET balance
if val >= 100:
  MULTI
  DECRBY balance 100
  EXEC
UNWATCH

Forget all keys WATCHed on the current connection, without running a transaction. EXEC and DISCARD already UNWATCH implicitly — call this explicitly only when you abandon a CAS attempt.

Common pitfall: A common CAS leak: you WATCH a key, read it, decide not to write, but forget to UNWATCH — the next MULTI/EXEC on that connection is now needlessly gated by the stale watch. Always UNWATCH on the early-return path.

Examples
WATCH balance
-- 读后决定不改
UNWATCH
WATCH a b c  -- 多 key 乐观锁
Persistence & replication (8)
SAVE

Synchronously dump the dataset to disk as RDB. BLOCKS THE SERVER for the entire duration — on a 10 GB dataset that is minutes. Almost never the right command in production.

Common pitfall: Use BGSAVE for non-blocking RDB snapshots. SAVE exists mainly for disaster recovery scripts that explicitly want server-quiescent point-in-time consistency.

Examples
SAVE  -- 一般别用
BGSAVE  -- 推荐
BGSAVE

Fork a background process to write an RDB snapshot without blocking the main thread. The fork itself can be slow on huge instances due to copy-on-write page-table cost.

Common pitfall: On a 64 GB instance with heavy writes, fork can take seconds and double resident memory while the child runs. Schedule BGSAVE during low traffic.

Examples
BGSAVE
BGSAVE SCHEDULE  -- 7.0+ 排队避免冲突
LASTSAVE

Return the UNIX timestamp of the most recent successful RDB save. Health checks compare this against now() to detect a stalled background save.

Examples
LASTSAVE  -- 比如返回 1716700000
SLAVEOF host port

Configure this instance as a replica of the given master, syncing the dataset and following the master's replication stream. Deprecated name — see REPLICAOF.

Common pitfall: Renamed to REPLICAOF in 5.0 for inclusive language. Both still work, but new tooling and configs should use REPLICAOF.

Examples
SLAVEOF master.internal 6379
SLAVEOF NO ONE  -- 解除从属变独立实例
REPLICAOF host port

Modern alias for SLAVEOF (5.0+). REPLICAOF NO ONE detaches from the master and promotes the instance to standalone primary.

Examples
REPLICAOF master.internal 6379
REPLICAOF NO ONE  -- 提升为主
BGREWRITEAOF

Rewrite the append-only file in the background, compacting it to the smallest set of commands that reproduce the current dataset. Keeps AOF replay fast and the file from growing without bound.

Common pitfall: Redis triggers an auto-rewrite based on auto-aof-rewrite-percentage, but a write-heavy spike can outpace it. Watch aof_pending_rewrite and aof_current_size in INFO persistence; trigger manually before the file gets unwieldy.

Examples
BGREWRITEAOF
INFO persistence  -- 看 aof_current_size / aof_base_size
WAIT numreplicas timeout

Block until the writes issued by this connection are acknowledged by at least numreplicas replicas, or until timeout ms. Buys stronger durability on top of async replication.

Common pitfall: WAIT is NOT a transaction and does NOT roll back if replicas fall short — it just tells you how many acked. Redis replication is asynchronous by default; WAIT narrows the data-loss window but cannot eliminate it.

Examples
WAIT 1 100  -- 至少 1 个副本确认,最多等 100ms
WAIT 2 1000  -- 多数派确认
FAILOVER [TO host port] [ABORT] [TIMEOUT ms]

Trigger a coordinated, low-data-loss failover from a primary to one of its replicas (6.2+). Unlike a Sentinel-driven failover, the primary pauses writes and hands off cleanly.

Examples
FAILOVER  -- 自动选副本
FAILOVER TO replica.internal 6379
FAILOVER ABORT  -- 中止进行中的切换
Server & client (11)
CLIENT LIST

List every connected client with its address, age, idle time, last command, and flags. Indispensable for diagnosing connection leaks and "who is hammering us".

Examples
CLIENT LIST
CLIENT LIST TYPE pubsub  -- 仅 pub/sub 客户端
CLIENT KILL ADDR 1.2.3.4:5678  -- 踢掉某客户端
INFO [section]

Return server stats in plain text: memory, replication, clients, persistence, CPU, keyspace, commandstats. The single most useful diagnostic command.

Examples
INFO  -- 全量
INFO memory
INFO replication
INFO commandstats  -- 各命令调用次数和耗时
CONFIG GET parameter

Read one or more server config parameters. Supports glob patterns (CONFIG GET maxmemory*). Read-only on managed Redis services like ElastiCache.

Examples
CONFIG GET maxmemory
CONFIG GET maxmemory-policy
CONFIG GET save
CONFIG SET parameter value

Set a config parameter at runtime, without restarting the server. The change is in-memory only — write CONFIG REWRITE to persist into redis.conf.

Common pitfall: CONFIG SET maxmemory-policy noeviction on a full instance will start refusing writes immediately. Validate the new policy is what you mean before changing it on prod.

Examples
CONFIG SET maxmemory 4gb
CONFIG SET maxmemory-policy allkeys-lru
CONFIG REWRITE  -- 落盘
FLUSHALL [ASYNC|SYNC]

Delete every key in EVERY database. ASYNC (4.0+) frees memory in a background thread. The fastest way to ruin a production weekend.

Common pitfall: Rename or disable in redis.conf for prod: rename-command FLUSHALL "". Equivalent for one DB only is FLUSHDB. Both are irreversible unless you have a recent RDB / AOF.

Examples
FLUSHALL ASYNC  -- 生产用 ASYNC
FLUSHDB  -- 仅当前库
DBSIZE

Return the number of keys in the currently selected database. O(1) — Redis tracks this count, unlike KEYS which would scan. The safe way to ask "how big is this DB".

Examples
DBSIZE  -- 比如 1240392
SELECT 1
DBSIZE  -- 看 1 号库
MEMORY USAGE key [SAMPLES n]

Estimate the total bytes a key and its value consume, including internal overhead. The right tool for hunting the handful of keys eating most of your memory.

Common pitfall: For aggregate types it samples nested elements rather than measuring all of them; bump SAMPLES (or use 0 for exact) on skewed collections. Pair with MEMORY DOCTOR for a plain-language health summary.

Examples
MEMORY USAGE user:1001  -- 字节数
MEMORY USAGE big_zset SAMPLES 0  -- 精确测量
MEMORY DOCTOR
SLOWLOG GET [count]

Return the most recent commands whose execution time exceeded slowlog-log-slower-than microseconds. The first place to look when latency spikes — it names the exact slow command and its args.

Common pitfall: Slowlog measures only command EXECUTION time, not the time a request waited in the queue behind a slow command. A fast command logged as "slow" usually means it was stuck behind a KEYS or a big Lua script.

Examples
SLOWLOG GET 10  -- 最近 10 条慢命令
SLOWLOG RESET  -- 清空
CONFIG SET slowlog-log-slower-than 10000  -- 阈值 10ms
CLIENT NO-EVICT on|off

Exempt the current connection from client-output-buffer eviction (7.0+) so a critical admin or monitoring client is not killed under memory pressure. Use sparingly.

Examples
CLIENT NO-EVICT on
CLIENT NO-TOUCH on  -- 读不更新 LRU/LFU(7.2+)
CLIENT SETNAME monitor-1
COMMAND DOCS [command ...]

Return structured documentation for commands — summary, arguments, complexity, flags. COMMAND COUNT gives the total, COMMAND INFO returns the arity and key-position metadata clients use for routing.

Examples
COMMAND COUNT  -- 服务器支持的命令总数
COMMAND INFO get set
COMMAND DOCS hset
CLUSTER INFO

Report the health of a Redis Cluster: state (ok / fail), how many of the 16384 hash slots are assigned, and the known/reachable node counts. First check when a cluster misbehaves.

Common pitfall: cluster_state:fail means some slots are unassigned and the cluster refuses queries that touch them. CLUSTER SLOTS / CLUSTER SHARDS show the slot-to-node map you need to diagnose a gap.

Examples
CLUSTER INFO
CLUSTER SLOTS
CLUSTER KEYSLOT user:1001  -- 这个 key 落哪个槽
Common pitfalls (12)
KEYS in production

Running KEYS * (or any pattern) on a production instance walks the entire keyspace synchronously and freezes Redis for seconds. Always use SCAN.

Common pitfall: Even pattern-bounded KEYS (KEYS user:*) walks ALL keys and matches each one. The cost is proportional to total keyspace, not match count. SCAN is incremental and yields between buckets.

Examples
KEYS *  -- 不要这样
SCAN 0 MATCH user:* COUNT 500  -- 正确做法
SCAN may miss or duplicate

SCAN guarantees that every key present from start to end of the full iteration is returned at least once, but elements added or removed DURING the scan may be missed or duplicated. Dedupe on the client.

Examples
# 用 Set 在客户端去重
seen = set()
cursor = 0
while True:
  cursor, batch = r.scan(cursor)
  for k in batch: seen.add(k)
  if cursor == 0: break
HGETALL on big hash

HGETALL on a hash with 100k+ fields returns megabytes in one reply, blocking the Redis event loop and the client. Switch to HSCAN, or shard the hash into N smaller hashes.

Examples
HSCAN big_hash 0 COUNT 500
-- 按 hash_tag 拆分: user:1001:profile, user:1001:prefs, user:1001:cache
Expired keys not freed immediately

When a TTL fires the key is NOT freed instantly — Redis uses lazy expiration (delete on next access) plus a probabilistic background sweep. Memory usage may include "expired but not yet freed" keys.

Common pitfall: INFO memory used_memory > sum(key sizes) is normal. If the gap is large, raise hz (CONFIG SET hz 100) to make the background sweep more aggressive, or accept some lag.

Examples
DEBUG SLEEP 0  -- 触发一次访问帮过期
CONFIG SET hz 100  -- 默认 10,调到 100 更激进
Memory fragmentation

Long-running Redis instances accumulate jemalloc fragmentation — used_memory_rss can be 1.5-2x used_memory. Check mem_fragmentation_ratio in INFO memory; > 1.5 warrants action.

Common pitfall: Enable active defrag at runtime: CONFIG SET activedefrag yes. It targets the issue while the server runs. The legacy fix — restart with persistence — also works but causes a failover window.

Examples
INFO memory  -- 看 mem_fragmentation_ratio
CONFIG SET activedefrag yes
AOF vs RDB trade-offs

RDB is a point-in-time snapshot — small, fast to load, can lose minutes on crash. AOF logs every write — large, slower to replay, durability tunable from "every write" to "every second" to "OS decides".

Common pitfall: Production default: BOTH on. RDB for fast recovery and ship-out backups, AOF (appendfsync everysec) for ≤1s data loss on crash. AOF needs periodic BGREWRITEAOF to compact.

Examples
CONFIG SET appendonly yes
CONFIG SET appendfsync everysec
BGREWRITEAOF  -- 压缩 AOF
Cache stampede on hot key

When a popular cached key expires, every concurrent request misses at once and slams the database to recompute the same value — a thundering herd. One slow backend query becomes thousands.

Common pitfall: Mitigate with a short-lived per-key lock (SET lock NX EX) so only one request recomputes while others serve stale or wait, or refresh slightly BEFORE expiry (probabilistic early expiration). Add jitter to TTLs so keys do not all expire together.

Examples
SET lock:recompute:home worker-7 NX EX 5  -- 只放一个进来重算
EXPIRE cache:home 60  -- 加随机 +rand(0,10) 防同时过期
Hot key / single slot bottleneck

In a cluster, every operation on one extremely popular key lands on a single shard, so that one node saturates while the rest idle. A global counter or a celebrity user is a classic hot key.

Common pitfall: Shard the hot key into N suffixed sub-keys (counter:0..counter:9) and sum on read, or cache the value in a client-local layer with a short TTL. Hash tags decide colocation — do NOT accidentally tag everything into one slot.

Examples
INCR counter:{shard:$((RANDOM%10))}  -- 写打散到 10 个子 key
CLUSTER KEYSLOT "{user}:1001"  -- 确认 hash tag 落槽
Big keys block the event loop

Redis is single-threaded for command execution, so one O(N) operation on a giant key (HGETALL on a million-field hash, DEL on a huge set) stalls EVERY other client for the whole duration.

Common pitfall: Find big keys offline with redis-cli --bigkeys or --memkeys (they sample, not block). Delete them with UNLINK, read them with the *SCAN family, and design schemas so no single key grows unbounded.

Examples
redis-cli --bigkeys  -- 扫描找大 key
redis-cli --memkeys  -- 按内存找
UNLINK the_big_key
maxmemory-policy eviction surprises

When memory hits maxmemory, what happens depends entirely on maxmemory-policy. noeviction rejects writes with OOM errors; allkeys-lru evicts any key; volatile-lru only evicts keys that have a TTL set.

Common pitfall: A volatile-* policy with NO keys carrying a TTL behaves like noeviction — writes start failing with no key ever evicted. If you rely on LRU eviction, either set TTLs on cache keys or use an allkeys-* policy.

Examples
CONFIG GET maxmemory-policy
CONFIG SET maxmemory-policy allkeys-lru  -- 纯缓存场景
INFO stats  -- 看 evicted_keys 是否在涨
EXPIRE on replica does not delete

Replicas do NOT independently expire keys — they wait for the primary to send an explicit DEL when the key expires. A read on a replica can briefly return a logically-expired key.

Common pitfall: Since Redis 3.2 replicas return nil for a logically-expired key on read even before the DEL arrives, so correctness holds — but the key still occupies memory on the replica until the primary propagates the delete. Do not assume replica memory tracks the primary exactly.

Examples
TTL session:abc  -- 主与副本上结果可能短暂不同
INFO keyspace  -- 对比主从 expires 计数
Numeric strings and float precision

Redis stores numbers as strings and parses them per command. A counter that grows past 2^63-1 overflows INCR; an INCRBYFLOAT chain accumulates IEEE-754 rounding error just like any other float math.

Common pitfall: For money never use INCRBYFLOAT on dollar amounts — store integer cents and INCRBY. For very large counters, watch the int64 ceiling or shard the counter so no single key overflows.

Examples
INCRBY wallet:42:cents 99  -- 存分,整数
INCR big_counter  -- 接近 9.22e18 时会溢出报错

What this tool does

Searchable Redis cheat sheet, 80+ entries that backend engineers, SREs and on-call folks actually type into redis-cli — not yet another "SET foo bar" tour. Fifteen sections: keys (GET / SET / DEL / EXPIRE / TTL / KEYS vs SCAN / TYPE / RENAME), strings (INCR / DECR / APPEND / GETSET / STRLEN / SETEX / SETNX vs SET NX EX), hashes (HSET multi-field, HMGET, HDEL, HGETALL danger, HINCRBYFLOAT), lists as queues (LPUSH / RPUSH / LPOP / RPOP / LRANGE / LREM / BLPOP for blocking consumers), sets (SADD / SISMEMBER / SUNION / SINTER / SDIFF with intersection order tricks), sorted sets (ZADD with NX/XX/GT/LT, ZRANGE 6.2+ swiss-army, ZRANGEBYSCORE for scheduled jobs, ZINCRBY, ZRANK), bitmaps for compact DAU flags (SETBIT / BITCOUNT / BITOP), HyperLogLog probabilistic cardinality (PFADD / PFCOUNT / PFMERGE), Pub/Sub fire-and-forget (PUBLISH / SUBSCRIBE / PSUBSCRIBE) and when to switch to Streams, Streams 5.0+ durable replayable log (XADD with MAXLEN, XREAD with BLOCK $, XREADGROUP for at-least-once consumer groups, XACK, XLEN), Lua scripts (EVAL, EVALSHA, SCRIPT LOAD with NOSCRIPT fallback), transactions (MULTI, EXEC, DISCARD, WATCH for optimistic locking — and the fact Redis transactions do NOT rollback on error), persistence and replication (SAVE vs BGSAVE, LASTSAVE for health checks, SLAVEOF / REPLICAOF, AOF vs RDB), server ops (CLIENT LIST, INFO sections, CONFIG GET/SET, FLUSHALL ASYNC), and the money-burning pitfalls (KEYS in production, SCAN duplicate semantics, HGETALL on a big hash, lazy expiration, memory fragmentation, AOF vs RDB trade-offs). Every entry: command + EN/ZH description + 1-3 real redis-cli-pasteable examples + common pitfall. Search across all fields plus category chips. Pure client-side — no Redis connection, no upload. Pair with our PostgreSQL, SQL, Docker, kubectl and nginx cheat sheets.

Tool details

Input
Text
The page exposes text boxes, numeric controls, file pickers, or structured inputs depending on the tool.
Output
Live result + Copy
The result area focuses on usable output, with copy, download, or preview actions when supported.
Privacy
Browser-side processing
The main tool logic does not call an external API, so inputs normally stay in the current tab.
Save / share
No account required
Open the page and use it; whether results survive refresh depends on the tool.
Performance budget
Initial JS <= 28 KB
No WASM budget is declared, keeping the tool quick to open on mobile.
Best fit
Developer & DevOps · Developer
Category and role tags drive related tools, internal links, and quick fit checks.

How to use

  1. 1. Input

    Paste or drop your content into the tool panel.

  2. 2. Process

    Click the button. All processing is local in your browser.

  3. 3. Copy / Download

    Copy the result or download to disk in one click.

How Redis Cheatsheet fits into your work

Use it before upload, handoff, archive, support review, or any moment where a file needs one local check before it leaves your machine.

File jobs

  • Checking file type, size, metadata, and obvious mismatch signals before sharing.
  • Preparing mixed folders for upload, archive, intake, or review.
  • Keeping sensitive files in the browser instead of sending them to an account-based service.

File checks

  • Do not treat the extension alone as proof of the real file type.
  • Review metadata before a file goes to customers, vendors, or a public page.
  • Keep the original file until the copied, converted, or exported result is verified.

Good next steps

These links move the current task into a more complete workflow.

  1. 1 Nginx Cheatsheet Nginx cheat sheet — common configs, location/server blocks, SSL, reverse proxy, gzip, real examples & gotchas. Open
  2. 2 PostgreSQL Cheatsheet PostgreSQL cheat sheet — 80+ commands & functions for psql, JSONB, CTEs, window functions, indexing, partitioning, advanced extensions. Open
  3. 3 SQL Cheatsheet SQL cheat sheet — 100+ statements covering SELECT, JOIN, window functions, indexing, MySQL/PostgreSQL/SQLite differences. Open

Real-world use cases

  • Building a SET-NX-EX distributed lock and getting the release right

    You are adding a cron-guard so two app boxes never run the same nightly billing job twice. You search "NX" and "EVAL", copy SET billing_lock $token NX EX 300, then grab the Lua release snippet that checks the token before DEL. The pitfall line reminds you that plain DEL would delete another box's freshly acquired lock after your 300s TTL expires.

  • Trimming a Stream that quietly grew to 8GB

    An on-call page says one Redis instance is at 90% maxmemory. You search "Streams" and "MAXLEN", find XADD stream MAXLEN ~ 1000000 and XTRIM stream MAXLEN ~ 1000000, and learn the approximate (~) form is far cheaper than exact trimming. The pitfall note explains an uncapped Stream grows forever, which is exactly what ate the 8GB.

  • Replacing a KEYS scan that froze production for 4 seconds

    A teammate shipped KEYS user:* in a request handler and the 10M-key instance stalled every connected client. You filter "Keys", read why KEYS is O(N) and blocks the single thread, then copy the SCAN 0 MATCH user:* COUNT 1000 cursor loop plus the reminder that SCAN can return the same key twice, so you dedupe client-side.

  • Picking volatile-lru so the lock keys do not get evicted

    Your cache instance also holds session and lock keys, and allkeys-lru just evicted an in-flight job lock at 3am. You search "eviction", set TTLs on the cache keys only, switch to maxmemory-policy volatile-lru, and confirm with CONFIG GET maxmemory-policy. The pitfall chip spelled out exactly the allkeys-lru footgun you hit.

Common pitfalls

  • Running plain SET key value to refresh a value but wiping its TTL — use SET key value KEEPTTL or re-specify EX so the expiry survives.

  • Pairing SETNX with a separate EXPIRE for a lock — if the client crashes between the two commands the lock never expires; use the atomic SET key token NX EX ttl instead.

  • Calling HGETALL on a hash you let grow to millions of fields — it returns megabytes in one blocking reply; use HSCAN with COUNT or HMGET only the fields you need.

Privacy

This cheat sheet is one static page. Your search text is matched against an in-memory array of commands entirely in your browser — it never touches a Redis server, never goes into the URL, and is never uploaded. Open DevTools Network while you type and you will see zero requests, so it is safe behind bastion-only Redis hosts and air-gapped networks.

FAQ

Tool combos

Folks in your role tend to reach for these alongside this tool.

Made by Toolora · 100% client-side · Updated 2026-06-12