Data types and the commands that matter
Strings, lists, hashes, sets and sorted sets — what each one is for, and why the O(N) commands are a production hazard.
Strings and lists
A Redis string holds up to 512 MB of binary-safe bytes, which means it also stores JSON, a serialised object, or a counter. Because command execution is single-threaded, operations like INCR and SETNX are atomic without any locking.
SET user:42:name "Ada" EX 3600 # with a one-hour TTL
SETNX lock:job:9 worker-3 # only if the key does not exist
GET user:42:name
APPEND user:42:name " Lovelace"
INCR stats:pageviews # atomic, creates the key at 0 first
INCRBY quota:42 -1
MSET a 1 b 2
MGET a b
LPUSH queue:email "m-1" "m-2" # push to the head
RPUSH queue:email "m-3"
LRANGE queue:email 0 -1 # read without removing
LPOP queue:email 2 # pop and return up to two
LTRIM notifications:42 0 99 # keep only the newest 100- Lists are linked lists: pushes and pops at either end are O(1), indexing into the middle is O(N).
LTRIMafter a push is the standard way to keep a capped feed or a bounded log per user.BLPOPandBRPOPblock until an element arrives — the classic simple queue, with the durability caveat covered later.- Key names are a flat namespace; the colon convention (
object:id:field) exists purely so humans andSCANpatterns stay readable.
Hashes, sets and sorted sets
HSET user:42 name "Ada" plan "pro" logins 12
HINCRBY user:42 logins 1
HGETALL user:42
HRANDFIELD user:42 -1
SADD post:9:likes 42 77 101
SISMEMBER post:9:likes 42
SINTER post:9:likes post:12:likes # users who liked both
SCARD post:9:likes
ZADD leaderboard 1500 alice 1200 bob 900 carol
ZINCRBY leaderboard 50 bob
ZREVRANGE leaderboard 0 9 WITHSCORES # top ten
ZRANGEBYSCORE leaderboard 1000 +inf
ZRANK leaderboard alice # 0-based position| Type | Model | Typical use |
|---|---|---|
| String | One value | Cache entries, counters, locks, JSON blobs |
| List | Ordered sequence, fast at both ends | Queues, activity feeds, capped logs |
| Hash | Field/value map per key | Objects whose fields change independently |
| Set | Unordered unique members | Tags, membership tests, intersections |
| Sorted set | Unique members with a score | Leaderboards, rankings, rate limiters, priority queues |
| Stream | Append-only log with IDs | Durable queues and consumer groups |
| Bitmap / HLL | Bit or cardinality sketch | Presence flags, unique-count estimates |
A sorted set scores lexicographic order too: when every member has the same score, ZRANGEBYLEX answers range queries on strings, which is how autocomplete indexes are often built.
Atomicity and the O(N) trap
MULTI
INCR stats:orders
ZADD leaderboard 10 alice
EXEC # both run, in order, with nothing in between
EVAL "return redis.call('GET', KEYS[1])" 1 user:42:name
SCAN 0 MATCH user:42:* COUNT 100 # safe cursor-based iteration
OBJECT ENCODING leaderboard # listpack or skiplist?
MEMORY USAGE user:42MULTI/EXECqueues commands but does not roll back: if one command fails at runtime the others still execute. Use a Lua script when you need all-or-nothing logic.- A Lua script runs atomically, which makes it the right tool for compare-and-set sequences that must not interleave.
KEYS pattern,HGETALL,SMEMBERS,LRANGE key 0 -1andFLUSHALLare O(N) and block every other client during execution.- Use the incremental scan family —
SCAN,HSCAN,SSCAN,ZSCAN— instead of the O(N) variants in production code.
⚠️
Command execution is single-threaded, so one slow command stalls the entire instance for every client. Run
SLOWLOG GET 25 and LATENCY DOCTOR when latency spikes; the culprit is almost always an O(N) command over a large key.FAQ
Why does Redis not use disk like a normal database?
It is designed to serve data from memory, where reads and writes cost microseconds. Disk is used for durability and restarts, not for serving reads, which is why everything must still fit in RAM.
How do I store an object?
A hash when individual fields are updated separately and the object is small; a serialised string when you always read or write the whole value. Hashes also allow partial reads without transferring everything.
Related
Expiry and caching patterns Pub/sub, queues and persistence
Last refreshed 2026-09-18.