Skip to content
Unverified — AI-generated content. Help verify this page

Redis Cheat Sheet

Quick reference for Redis data types, essential commands, common patterns, Lua scripting, and cluster operations.

Deep dive: Redis Internals | Redis Caching Patterns | Redis Streams


Connection & Server

CommandDescription
redis-cliConnect to local Redis
redis-cli -h host -p 6379 -a passwordConnect with auth
redis-cli --tlsConnect with TLS
PINGTest connection (returns PONG)
AUTH passwordAuthenticate
SELECT 0Switch to database 0
DBSIZENumber of keys in current DB
INFOServer info and stats
INFO memoryMemory usage details
INFO keyspaceKeys per database
CONFIG GET maxmemoryGet config value
CONFIG SET maxmemory 1gbSet config at runtime
MONITORReal-time command stream (debug only)
SLOWLOG GET 10Last 10 slow commands
CLIENT LISTConnected clients
FLUSHDBDelete all keys in current DB
FLUSHALLDelete all keys in all DBs

Data Types & Commands

Strings

The simplest type. Stores text, numbers, or binary data up to 512 MB.

redis
SET key "value"                  -- Set a key
SET key "value" EX 3600          -- Set with 1 hour TTL
SET key "value" NX               -- Set only if not exists
SET key "value" XX               -- Set only if exists
SETNX key "value"                -- Set if not exists (atomic)
MSET k1 "v1" k2 "v2"            -- Set multiple
GET key                          -- Get value
MGET k1 k2 k3                   -- Get multiple
GETSET key "new"                 -- Set and return old value
INCR counter                     -- Increment by 1
INCRBY counter 5                 -- Increment by 5
DECR counter                     -- Decrement by 1
INCRBYFLOAT price 0.5            -- Increment float
APPEND key " more"               -- Append to string
STRLEN key                       -- String length
GETRANGE key 0 4                 -- Substring

Hashes

Key-value pairs within a key. Perfect for objects.

redis
HSET user:1 name "Alice" age 30 email "alice@ex.com"
HGET user:1 name                 -- Get single field
HMGET user:1 name email          -- Get multiple fields
HGETALL user:1                   -- Get all fields and values
HDEL user:1 email                -- Delete field
HEXISTS user:1 name              -- Check field exists
HKEYS user:1                     -- All field names
HVALS user:1                     -- All values
HLEN user:1                      -- Number of fields
HINCRBY user:1 age 1             -- Increment numeric field
HSETNX user:1 name "Bob"         -- Set field only if not exists

Lists

Ordered collection of strings. Doubly-linked list under the hood.

redis
LPUSH queue "item1"              -- Push to head
RPUSH queue "item2"              -- Push to tail
LPOP queue                       -- Pop from head
RPOP queue                       -- Pop from tail
BLPOP queue 30                   -- Blocking pop (30s timeout)
BRPOP queue 30                   -- Blocking pop from tail
LLEN queue                       -- List length
LRANGE queue 0 -1                -- Get all elements
LRANGE queue 0 9                 -- Get first 10
LINDEX queue 0                   -- Get by index
LSET queue 0 "new"               -- Set by index
LTRIM queue 0 99                 -- Keep only first 100
LPOS queue "item1"               -- Find position
LMOVE src dst LEFT RIGHT         -- Move between lists

Sets

Unordered collection of unique strings.

redis
SADD tags "redis" "cache" "db"   -- Add members
SREM tags "db"                   -- Remove member
SISMEMBER tags "redis"           -- Check membership
SMEMBERS tags                    -- All members
SCARD tags                       -- Set size
SRANDMEMBER tags 2               -- 2 random members
SPOP tags                        -- Remove and return random
SUNION tags1 tags2               -- Union
SINTER tags1 tags2               -- Intersection
SDIFF tags1 tags2                -- Difference (in tags1 not in tags2)
SUNIONSTORE dest tags1 tags2     -- Store union result

Sorted Sets

Like sets but each member has a score. Sorted by score.

redis
ZADD leaderboard 100 "alice"     -- Add with score
ZADD leaderboard 95 "bob" 110 "charlie"
ZSCORE leaderboard "alice"       -- Get score
ZRANK leaderboard "alice"        -- Rank (0-based, low to high)
ZREVRANK leaderboard "alice"     -- Rank (high to low)
ZRANGE leaderboard 0 9           -- Top 10 (low to high)
ZREVRANGE leaderboard 0 9        -- Top 10 (high to low)
ZRANGEBYSCORE lb 90 100          -- Members with score 90-100
ZRANGEBYSCORE lb -inf +inf       -- All by score
ZCARD leaderboard                -- Set size
ZCOUNT leaderboard 90 100        -- Count in score range
ZINCRBY leaderboard 5 "alice"    -- Increment score
ZREM leaderboard "bob"           -- Remove member
ZREMRANGEBYRANK lb 0 -4          -- Keep only top 3
ZRANGEBYSCORE lb 90 100 LIMIT 0 5 -- Paginate

Streams

Append-only log structure for event streaming.

redis
XADD stream * field1 value1      -- Append entry (auto-ID)
XADD stream 1234-0 field1 value1 -- Append with specific ID
XLEN stream                      -- Stream length
XRANGE stream - +                -- All entries
XRANGE stream - + COUNT 10       -- First 10 entries
XREVRANGE stream + -             -- Reverse order
XREAD COUNT 10 STREAMS stream 0  -- Read from beginning
XREAD BLOCK 5000 STREAMS s $     -- Block-read new entries (5s)

-- Consumer groups
XGROUP CREATE stream group 0     -- Create consumer group
XREADGROUP GROUP group consumer COUNT 10 STREAMS stream >
XACK stream group id             -- Acknowledge message
XPENDING stream group            -- Pending messages info
XCLAIM stream group consumer 60000 id -- Claim stale message

Key Management

CommandDescription
EXISTS keyCheck if key exists
DEL keyDelete key (blocking)
UNLINK keyDelete key (non-blocking)
TYPE keyGet key type
RENAME key newkeyRename key
EXPIRE key 3600Set TTL in seconds
PEXPIRE key 60000Set TTL in milliseconds
EXPIREAT key timestampSet expiry at Unix time
TTL keyRemaining TTL in seconds
PTTL keyRemaining TTL in milliseconds
PERSIST keyRemove expiry
KEYS patternFind keys (NEVER in production)
SCAN 0 MATCH "user:*" COUNT 100Iterate keys safely
OBJECT ENCODING keyInternal encoding
MEMORY USAGE keyMemory used by key
DUMP keySerialize key
RESTORE key 0 dataDeserialize key

WARNING

Never use KEYS * in production. It blocks the server. Always use SCAN instead.


Common Patterns

Cache-Aside Pattern

Read:  Check cache -> miss -> read DB -> write cache -> return
Write: Write DB -> invalidate cache
redis
-- Read: check cache first
GET user:123
-- If nil, read from DB and cache
SET user:123 "{json}" EX 3600

-- Write: invalidate after DB write
DEL user:123

Distributed Lock

redis
-- Acquire lock (NX = only if not exists, EX = TTL)
SET lock:resource unique_id NX EX 30

-- Release lock (only if we own it) -- use Lua for atomicity
EVAL "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end" 1 lock:resource unique_id

Rate Limiter (Sliding Window)

redis
-- Using sorted set for sliding window
ZADD ratelimit:user:123 <now_ms> <request_id>
ZREMRANGEBYSCORE ratelimit:user:123 0 <now_ms - window_ms>
ZCARD ratelimit:user:123
EXPIRE ratelimit:user:123 <window_seconds>

Pub/Sub

redis
-- Subscriber
SUBSCRIBE channel
PSUBSCRIBE "events:*"           -- Pattern subscribe

-- Publisher
PUBLISH channel "message"

Session Storage

redis
-- Store session as hash
HSET session:abc123 user_id 42 role "admin" created_at 1234567890
EXPIRE session:abc123 86400     -- 24 hour TTL

-- Extend session on activity
EXPIRE session:abc123 86400     -- Reset TTL

-- Get session
HGETALL session:abc123

Counter with Expiry

redis
-- Page view counter (daily)
INCR pageviews:2026-03-18:/home
EXPIRE pageviews:2026-03-18:/home 172800  -- Keep 2 days

Leaderboard

redis
-- Add/update score
ZINCRBY leaderboard 10 "player:42"

-- Get top 10
ZREVRANGE leaderboard 0 9 WITHSCORES

-- Get player rank (1-based)
ZREVRANK leaderboard "player:42"  -- Add 1 for 1-based

Lua Scripting

Why Lua?

  • Atomic execution (no other commands run during script)
  • Reduce round trips (multiple operations in one call)
  • Complex conditional logic

Basic Syntax

redis
EVAL "return redis.call('GET', KEYS[1])" 1 mykey
-- KEYS[1] = first key argument
-- ARGV[1] = first non-key argument

-- Multi-command script
EVAL "
  local current = redis.call('GET', KEYS[1])
  if current then
    return redis.call('INCR', KEYS[1])
  else
    redis.call('SET', KEYS[1], ARGV[1])
    return tonumber(ARGV[1])
  end
" 1 counter 100

Common Lua Scripts

redis
-- Compare and delete (safe lock release)
EVAL "
  if redis.call('GET', KEYS[1]) == ARGV[1] then
    return redis.call('DEL', KEYS[1])
  end
  return 0
" 1 lock:resource owner_id

-- Rate limiter (fixed window)
EVAL "
  local key = KEYS[1]
  local limit = tonumber(ARGV[1])
  local window = tonumber(ARGV[2])
  local current = redis.call('INCR', key)
  if current == 1 then
    redis.call('EXPIRE', key, window)
  end
  if current > limit then
    return 0
  end
  return 1
" 1 ratelimit:user:123 100 60

-- Get or set with TTL
EVAL "
  local val = redis.call('GET', KEYS[1])
  if val then
    return val
  end
  redis.call('SET', KEYS[1], ARGV[1], 'EX', ARGV[2])
  return ARGV[1]
" 1 cache:key "computed_value" 3600

Loading Scripts

redis
-- Load script and get SHA
SCRIPT LOAD "return redis.call('GET', KEYS[1])"
-- Returns SHA hash

-- Execute by SHA (more efficient)
EVALSHA <sha> 1 mykey

-- Check if script is cached
SCRIPT EXISTS <sha>

Cluster Operations

Cluster Info

CommandDescription
CLUSTER INFOCluster state overview
CLUSTER NODESAll nodes and slots
CLUSTER SLOTSSlot-to-node mapping
CLUSTER MYIDCurrent node ID
CLUSTER KEYSLOT keyHash slot for a key

Cluster Management

CommandDescription
CLUSTER MEET host portAdd node to cluster
CLUSTER ADDSLOTS 0 1 2 ... 5460Assign hash slots
CLUSTER REPLICATE node_idMake current node a replica
CLUSTER FAILOVERManual failover
CLUSTER RESETReset cluster config
CLUSTER FORGET node_idRemove node from cluster

redis-cli Cluster Mode

bash
# Connect in cluster mode
redis-cli -c -h host -p 6379

# Create cluster
redis-cli --cluster create host1:6379 host2:6379 host3:6379 \
  host4:6379 host5:6379 host6:6379 --cluster-replicas 1

# Check cluster health
redis-cli --cluster check host:6379

# Reshard
redis-cli --cluster reshard host:6379

# Add node
redis-cli --cluster add-node new_host:6379 existing_host:6379

# Rebalance slots
redis-cli --cluster rebalance host:6379

Hash Tags (Force Same Slot)

redis
-- Keys with same hash tag go to same slot
SET {user:123}.profile "data"
SET {user:123}.settings "data"
-- Both in same slot, can use in multi-key commands

Memory Optimization

Eviction Policies

PolicyDescription
noevictionReturn error when full (default)
allkeys-lruEvict least recently used
allkeys-lfuEvict least frequently used
volatile-lruLRU among keys with TTL
volatile-lfuLFU among keys with TTL
volatile-ttlEvict keys with shortest TTL
allkeys-randomRandom eviction
volatile-randomRandom among keys with TTL

Memory Commands

redis
INFO memory                      -- Memory overview
MEMORY USAGE key                 -- Bytes used by key
MEMORY DOCTOR                    -- Memory issues diagnosis
MEMORY STATS                     -- Detailed memory stats
CONFIG SET maxmemory 2gb         -- Set memory limit
CONFIG SET maxmemory-policy allkeys-lru

Persistence

ModeDescriptionData SafetyPerformance
RDBPoint-in-time snapshotsMay lose last minutesBetter
AOFAppend every writeBetter durabilitySlower
RDB + AOFBoth enabledBest durabilitySlowest
NoneNo persistenceData loss on restartFastest
redis
-- Manual snapshot
BGSAVE

-- Manual AOF rewrite
BGREWRITEAOF

-- Last save timestamp
LASTSAVE

When to Use X vs Y

DecisionChoice AChoice BUse A WhenUse B When
Data typeStringHashSingle value, counterObject with fields
QueueListStreamSimple FIFOConsumer groups, persistence
Unique itemsSetSorted SetNo ordering neededNeed ranking/scoring
CachingString + EXHash + EXPIRESimple key-valueMultiple fields per cache entry
MessagingPub/SubStreamsFire-and-forgetNeed delivery guarantees
CounterINCRSorted SetSimple counterNeed ranking of counters
LockSET NX EXRedlockSingle instanceDistributed cluster

Troubleshooting

ProblemDiagnosis
High latencySLOWLOG GET 10, check INFO commandstats
Memory too highMEMORY DOCTOR, check INFO memory
Too many connectionsCLIENT LIST, check INFO clients
Keys not expiringCheck maxmemory-policy, run INFO keyspace
Cluster slot errorsCLUSTER INFO, CLUSTER NODES
Replication lagINFO replication, check master_link_status

Test Yourself
  1. What command sets a key only if it does not already exist?SET key "value" NX or SETNX key "value"

  2. How do you get all fields and values of a hash?HGETALL key

  3. What command blocks until an element is available in a list (with 30s timeout)?BLPOP queue 30

  4. How do you get the top 10 members of a sorted set from highest to lowest score?ZREVRANGE leaderboard 0 9

  5. What command should you NEVER use in production to find keys?KEYS * -- use SCAN instead.

  6. How do you delete a key without blocking the server?UNLINK key

  7. What Lua function executes a Redis command inside a script?redis.call('COMMAND', KEYS[1], ARGV[1])

  8. How do you force keys with the same hash tag into the same cluster slot? Wrap the common part in braces: {user:123}.profile and {user:123}.settings

  9. What eviction policy evicts the least recently used key?allkeys-lru

  10. How do you create a consumer group for a Redis Stream?XGROUP CREATE stream group 0

Common Gotchas

  • Using KEYS * in production. It blocks the single-threaded Redis server while scanning all keys. Use SCAN with COUNT for safe iteration.
  • Forgetting to set TTLs on cache keys. Without expiry, Redis fills up and either returns errors (noeviction) or evicts keys you may still need.
  • Using DEL on large keys. Deleting a key with millions of elements blocks Redis. Use UNLINK for non-blocking deletion.
  • Not using Lua for multi-step atomic operations. Without Lua, another client can modify state between your GET and SET, causing race conditions.

One-Liner Summary

Redis is an in-memory data structure store that makes caching, queuing, rate limiting, and real-time leaderboards trivially fast -- just remember it is single-threaded, so never block it.

"What I cannot create, I do not understand." — Richard Feynman