Understanding Redis Set and Sorted Set Internal Encodings: intset, hashtable, skiplist, and ziplist
This article explains how Redis stores Set and Sorted Set objects using dual internal representations—intset and hashtable for sets, skiplist and ziplist for sorted sets—detailing their structures, encoding selection criteria, upgrade processes, command usage, and the reasons behind combining dictionaries with skiplists for optimal performance.
Redis provides a Set data type whose internal representation can be either intset (integer set) or hashtable . The intset stores only integer values using three possible integer sizes ( int16_t , int32_t , int64_t ) and chooses the smallest encoding that fits all elements. Its C definition is:
typedef struct intset {
uint32_t encoding; // encoding type
uint32_t length; // number of elements
int8_t contents[]; // actual elements (type depends on encoding)
} intset;The encoding field can be INTSET_ENC_INT16 , INTSET_ENC_INT32 , or INTSET_ENC_INT64 , determining the range of values stored in contents[] . When a new element exceeds the current range, the intset is upgraded through four steps: expand the array, convert existing elements, insert the new element at the head or tail, and update the encoding and length.
If a set contains non‑integer elements or exceeds the configured entry limit ( set-max-intset-entries ), Redis switches to the hashtable representation, which is the same structure used for hash objects.
Sorted Sets ( zset ) use either a skiplist or a ziplist . The skiplist implementation stores each element as a zskiplistNode :
typedef struct zskiplistNode {
sds ele; // element string
double score; // double score
struct zskiplistNode *backward; // backward pointer
struct zskiplistLevel {
struct zskiplistNode *forward; // forward pointer
unsigned long span; // distance to next node
} level[];
} zskiplistNode;A zskiplist holds a header, tail, length, and the maximum level:
typedef struct zskiplist {
struct zskiplistNode *header, *tail;
unsigned long length;
int level;
} zskiplist;The final zset combines a dictionary (for O(1) element lookup) and a skiplist (for O(log N) range queries), achieving both fast exact lookups and ordered range operations.
When the sorted set is small (default zset-max-ziplist-entries = 128) and each element’s total length is under 64 bytes, Redis stores it as a ziplist to save memory.
Common commands for Sets include sadd , sismember , srem , smove , and smembers . For Sorted Sets, commands such as zadd , zscore , zincrby , zrange , zrevrange , zrangebyscore , zlexcount , etc., are demonstrated.
The article also provides a step‑by‑step test script that creates sets and sorted sets, inspects their types with type and encodings with object encoding , and shows how the encoding changes after inserting non‑integer elements or exceeding size thresholds.
In summary, the piece analyses the internal storage mechanisms of Redis Set and Sorted Set objects, explains the upgrade logic of integer sets, the dual‑structure design of sorted sets, and why Redis combines dictionaries with skiplists to achieve both constant‑time lookups and efficient ordered operations.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.