Understanding Redis Ziplist: Structure, Encoding, and Chain Updates
This article explains Redis's ziplist—a compact list implementation used for small integers and short strings—by detailing its memory layout, field meanings, entry encoding schemes, the role of previous_entry, and the chain‑update behavior that occurs when nodes are added or removed.
When a Redis list contains only a few items consisting of small integers or short strings, Redis stores the data using a special compact structure called a ziplist . A ziplist is a contiguous memory block that can be thought of as an array, but it also stores metadata such as total length, tail offset, and the length of the previous entry.
The ziplist header consists of four fields:
Field
Type
Length
Purpose
zlbytes
uint32_t
4 bytes
Total number of bytes occupied by the ziplist.
zltail
uint32_t
4 bytes
Offset of the tail entry from the start of the ziplist.
zllen
uint16_t
2 bytes
Number of entries (max 65,535; larger lists require traversal to count).
entry …
entry
variable
Actual data nodes; length is dynamic.
zlend
uint8_t
1 byte
Fixed value 0xFF marking the end of the ziplist.
Each entry consists of three parts: previous_entry , encoding , and content . The previous_entry field stores the length of the preceding node. It normally uses a single byte, but if the length exceeds 254 bytes, Redis expands it to five bytes: the first byte is set to 0xFE and the following four bytes hold the actual length. This design allows Redis to keep most entries compact while still supporting larger nodes.
Previous Entry
The previous_entry field can occupy up to five bytes. Redis first tries to store the length in one byte; only when the length is greater than 254 does it switch to the five‑byte representation. The special marker 0xFE is used because 0xFF is reserved for the zlend terminator.
Encoding
The encoding byte describes both the data type and the length of the entry's payload. The two most‑significant bits indicate the type:
00 : string with length ≤ 63 bytes (1‑byte encoding).
01 : string with length ≤ 16,383 bytes (2‑byte encoding).
10 : string with length ≤ 4,294,967,295 bytes (5‑byte encoding).
11 : integer (various integer sizes).
After stripping the two type bits, the remaining bits represent the length of the payload. The following table summarizes the possible encodings:
Encoding
Length (bytes)
Value
00aaaaaa
1
String length ≤ 63
01pppppp|qqqqqqqq
2
String length ≤ 16,383
10xxxxxx|qqqqqqqq|rrrrrrrr|ssssssss|tttttttt
5
String length ≤ 4,294,967,295
11000000
1
int16
11010000
1
int32
11100000
1
int64
11110000
1
24‑bit signed integer
11111110
1
8‑bit signed integer
1111xxxx (xxxx = 0000‑1101)
1
Values 0‑12
11111111
1
Ziplist end marker (0xFF)
Example: 00001000
The leading bits are 00 , indicating a short string. The remaining six bits 001000 equal 8 in decimal, so the entry stores a 1‑byte string of length 8.
Example: 01000001,00000000
The leading bits 01 denote a 2‑byte string. The following 14 bits represent the length 256, meaning the entry holds 256 bytes of data (e.g., 32 English characters if each occupies 8 bytes).
Content
The content field stores the actual payload, which can be either a string or an integer as described by the encoding. Because the length is already encoded, the parser does not need to examine the payload to determine the entry size.
When many entries have lengths in the range 250‑254 bytes, adding a new 254‑byte node at the head forces the first entry's previous_entry to expand from 1 to 5 bytes, which in turn shifts the offsets of subsequent entries. This ripple effect is called a chain update . Deleting nodes can trigger a similar cascade.
In summary, ziplist is optimal for storing a small number of short strings or integers, offering memory efficiency through compact headers, variable‑length previous_entry , and concise encodings, while chain updates remain rare due to the limited use case.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
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.