How it works
The explanation, with examples you can run.
The core types
All of these outputs come from redis-cli:
# String: bytes up to 512 MB; also counters> SET user:42:name AnaOK> INCR page:home:views(integer) 1> INCRBY page:home:views 10(integer) 11 # Hash: fields under one key> HSET user:42 name Ana country DK plan pro(integer) 3> HINCRBY user:42 logins 1(integer) 1 # List: ordered, push and pop at both ends> LPUSH jobs:email j1 j2 j3(integer) 3> RPOP jobs:email"j1" # Set: unique members> SADD post:7:likes u1 u2 u3 u2(integer) 3> SISMEMBER post:7:likes u9(integer) 0 # Sorted set: members ordered by a score> ZADD leaderboard 3100 ana 2900 ben 3350 cy(integer) 3> ZINCRBY leaderboard 300 ben"3200"> ZRANGE leaderboard 0 -1 REV WITHSCORES1) "cy"2) "3350"3) "ben"4) "3200"5) "ana"6) "3100"SADD counted three, not four: u2 was already there. Streams, an append-only log with consumer groups, have their own topic later.
Choosing
| You want | Use | Commands |
|---|---|---|
| A cached blob, a flag, a counter | String | GET, SET, INCR, SET ... NX |
| An object whose fields change separately | Hash | HSET, HGET, HINCRBY |
| A simple queue or a capped recent-items list | List | LPUSH, RPOP, BLMOVE, LTRIM |
| Uniqueness and membership | Set | SADD, SISMEMBER, SINTER |
| Ranking, by score or by time | Sorted set | ZADD, ZINCRBY, ZRANGE, ZREMRANGEBYSCORE |
| An event log with acknowledgements | Stream | XADD, XREADGROUP, XACK |
Some patterns: a sorted set with timestamps as scores is a time-ordered index (ZRANGE ... BYSCORE for a time window) or a sliding-window rate limiter. LPUSH plus LTRIM 0 99 keeps the latest hundred items. A set per tag plus SINTER answers "posts with both tags".
Encodings and size
Redis picks an internal encoding per value. Small hashes, lists, sets and sorted sets use a listpack, a compact contiguous block; above a size threshold (configurable, for example hash-max-listpack-entries) they convert to a hash table or skip list, which is faster for large sizes and uses more memory. Strings holding integers are stored as integers.
> OBJECT ENCODING user:42"listpack"> OBJECT ENCODING page:home:views"int"> MEMORY USAGE user:42(integer) 84This is why many small hashes can take less memory than the same data as separate string keys: each top-level key has its own overhead.
Naming keys
Keys are binary-safe strings; the convention is colon-separated segments, object:id:field, such as user:42:sessions. Keep them readable but not huge, and never rely on listing them with KEYS in production. If you need to find all keys for a user, keep that index yourself, for example in a set.
Check yourself
3 questions. Get them all right to finish this topic.
0 of 3 right so far. Get all three to finish this topic.