Redis Lists, Sets, and Sorted Sets: Internal Layout and Practical Patterns

Redis List

Storage Semantics

A Redis List is an ordered sequence of strings that preserves insertion order and allows duplicates. The theoretical upper bound is 2³²-1 (~4 billion) entries.

Core Commands

# Left-push elements
lpush inbox msg1
lpush inbox msg2 msg3
lpush inbox msg4 msg5

# Left-pop elements
lpop inbox
lpop inbox

# Random access
lindex inbox 0

# Full scan
lrange inbox 0 -1

Internal Representation

  • ≤3.0: dual strategy—ziplist for small lists, adlist for large ones.
  • ≥3.2: quicklist, a hybrid that chains multiple ziplists through a doubly-linked skeleton.
object encoding inbox   # returns "quicklist"

quicklist Layout

typedef struct quicklist {
    quicklistNode *head, *tail;
    unsigned long count;   /* total elements across all ziplists */
    unsigned long len;       /* number of quicklistNodes */
    int fill : QL_FILL_BITS; /* max ziplist size (entries or bytes) */
    unsigned int compress : QL_COMP_BITS; /* LZF compression depth */
    unsigned int bookmark_count : QL_BM_BITS;
    quicklistBookmark bookmarks[];
} quicklist;

typedef struct quicklistNode {
    struct quicklistNode *prev, *next;
    unsigned char *zl;     /* pointer to the ziplist blob */
    unsigned int sz;        /* byte size of this ziplist */
    unsigned int count : 16;
    unsigned int encoding : 2;   /* RAW=1, LZF=2 */
    unsigned int container : 2;    /* 2=ziplist */
    unsigned int attempted_compress : 1;
    unsigned int extra : 10;
} quicklistNode;
redis.conf directive Meaning
list-max-ziplist-size Positive = max entries; negative = max bytes (-5 = 64 KB).
list-compress-depth 0 = no compression; 1 = don’t compress ends; 2 = don’t compress ends+1, etc.

Typical Use-Cases

  • Activity feeds, comment threads, message queues.
  • Queue/Stack semantics via rpush+blpop (FIFO) or rpush+brpop (LIFO).

Redis Set

Storage Semantics

An unordered collection of unique strings, capped at 2³²-1 members.

Core Commends

sadd tags redis database cache
smembers tags
scard tags
srandmember tags
spop tags
srem tags cache
sismember tags redis

Internal Representation

  • intset when all members are integers and the set is small.
  • hashtable otherwise (value field is NULL).
typedef struct intset {
    uint32_t encoding;  /* INTSET_ENC_INT16/32/64 */
    uint32_t length;
    int8_t contents[];
} intset;

Switch threshold controlled by:

set-max-intset-entries 512

Typical Use-Cases

  • Lottery draws (spop).
  • Like/Check-in counters (sadd).
  • Tagging & filtering (sinter, sdiff, sunion).
  • Social graphs (follow/followers).

Redis Sorted Set (ZSET)

Storage Semantics

Ordered set where every member carries a score; ordering is ascending by score, then lexicographically by member when scores tie.

Structure Duplicates Ordered Ordering Key
List yes yes index
Set no no —
ZSet no yes score

Core Commands

zadd leaderboard 100 alice 200 bob 150 carol
zrange leaderboard 0 -1 withscores
zrevrange leaderboard 0 -1 withscores
zrangebyscore leaderboard 100 200
zrem leaderboard bob carol
zcard leaderboard
zincrby leaderboard 30 alice
zcount leaderboard 100 300
zrank leaderboard alice
zscore leaderboard alice

Internal Representation

  • ziplist when entries < 128 and member_len < 64 bytes.
  • skiplist + dict otherwise.
zset-max-ziplist-entries 128
zset-max-ziplist-value 64

Skip-list Details

A probabilistic multi-level index that gives average O(log N) search/insert/delete.

Level generation (server.c):

int zslRandomLevel(void) {
    int level = 1;
    while ((random()&0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
        level += 1;
    return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
}

Structures

typedef struct zskiplistNode {
    sds ele;
    double score;
    struct zskiplistNode *backward;
    struct zskiplistLevel {
        struct zskiplistNode *forward;
        unsigned long span;
    } level[];
} zskiplistNode;

typedef struct zskiplist {
    struct zskiplistNode *header, *tail;
    unsigned long length;
    int level;
} zskiplist;

typedef struct zset {
    dict *dict;          /* member → score map */
    zskiplist *zsl;      /* score ordered skip-list */
} zset;

Typical Use-Cases

  • Leaderboards (news, games).
  • Real-time trending (zincrby, zrevrange).

Example: increment article 6001’s clicks and fetch top 15:

zincrby hotNews:20251111 1 n6001
zrevrange hotNews:20251111 0 14 withscores

Tags: Redis data-structures list Set sorted-set

Posted on Fri, 02 Oct 2026 16:04:42 +0000 by Hybrid Kill3r