Redis Quicklist vs Listpack: Memory‑Performance Secrets Every Java Engineer Should Know

Redis’s evolution from linked lists to ziplist, quicklist, and the newer listpack is examined in depth, highlighting their structures, memory‑performance trade‑offs, operational details, and practical guidance for Java developers on choosing the right data structure for different workloads.

JavaEdge
JavaEdge
JavaEdge
Redis Quicklist vs Listpack: Memory‑Performance Secrets Every Java Engineer Should Know

0 Introduction

Redis is a high‑performance in‑memory key‑value store whose List type has evolved from a simple linked list to compressed structures such as ziplist, quicklist, and the newer listpack. This article analyses quicklist and listpack, explaining their design, memory‑performance trade‑offs, and when to use each.

Redis List Structure Evolution

Early Redis versions stored List data as a linked list, which offers fast insert/delete but suffers from poor memory locality and higher consumption. To improve memory usage, Redis introduced ziplist, a compact contiguous memory representation. As data grew, ziplist showed performance bottlenecks, prompting the development of quicklist (a hybrid of linked list and ziplist) and, in Redis 5.0, listpack as a more efficient replacement for ziplist.

1 Quicklist: Combining Linked List and Compressed List

1.1 Structure Overview

Quicklist is a hybrid structure that links multiple ziplist instances via a doubly‑linked list. Each node contains a ziplist, allowing fast insert/delete while keeping memory usage low.

struct quicklist {
    quicklistNode *head;
    quicklistNode *tail;
    unsigned long count;        /* List element count */
    unsigned int len;           /* Number of quicklistNodes */
    int fill : 16;              /* Fill factor for individual nodes */
    unsigned int compress : 16; /* Depth of end nodes not to compress */
};

Each quicklistNode holds a ziplist. The fill parameter controls how many elements each node can store, while compress determines how many nodes at the ends remain uncompressed to improve hot‑spot performance.

1.2 Operations

Insertion : When inserting an element, Redis checks the target node’s ziplist for free space. If space exists, the element is added directly; otherwise a new quicklistNode is created and linked.

Deletion : Deletion locates the element’s ziplist and removes it. If a ziplist becomes empty, its quicklistNode is freed.

1.3 Memory and Performance Trade‑offs

Quicklist balances memory efficiency and operation speed. Compressed ziplists reduce fragmentation, while the surrounding doubly‑linked list maintains fast insert/delete. Tuning the fill factor is crucial for achieving the desired memory‑performance balance.

2 Listpack: The Successor to Ziplist

Redis 5.0 introduced Listpack, a compact, contiguous memory structure that stores variable‑length strings or integers with lower overhead than ziplist. It is primarily used in Sorted Set, Hash, and Stream implementations.

2.1 Structure Overview

struct listpack {
    unsigned char *entry_start; // Listpack entries start here
    unsigned int total_bytes;   // Total size of the listpack
    unsigned int num_entries;   // Number of entries in the listpack
};

Listpack uses variable‑length encoding, reducing per‑entry metadata compared to ziplist, which results in better memory efficiency for small collections.

2.2 Optimizations

Memory Optimization : Encodes integers in a single byte when possible, cutting metadata overhead.

Performance Optimization : Simpler layout yields faster insert/delete and traversal, especially for small datasets.

2.3 Use Cases

Listpack is employed in Redis Sorted Set, Hash, and Stream structures. For tiny collections it offers excellent memory usage; as data grows, Redis may convert it to more complex structures such as skiplist or hash tables.

3 Quicklist vs Listpack Comparison

Structure Type : Quicklist = linked list + ziplist; Listpack = compact contiguous memory.

Primary Scenarios : Quicklist for Redis List; Listpack for Sorted Set and Hash.

Memory Footprint : Quicklist – moderate, tunable; Listpack – very low.

Insert/Delete Performance : Both good; Quicklist excels with frequent modifications, Listpack shines with small static collections.

Growth Behavior : Quicklist splits into multiple ziplists; Listpack converts to more complex structures when size increases.

4 Takeaways for Java Developers

Balancing Memory and Performance : Quicklist shows how combining a linked list with a compact representation can achieve both low memory usage and fast updates. Java developers can apply similar trade‑offs when selecting data structures for different workloads.

Cache‑Friendly Design : Compact storage improves CPU cache locality, a principle useful for high‑throughput Java services.

Variable‑Length Encoding : Listpack’s encoding strategy inspires efficient serialization techniques for small integers or strings in Java.

5 Conclusion

Quicklist and Listpack illustrate distinct design philosophies for optimizing memory and performance in Redis. Understanding these internals helps Java engineers make informed decisions about data structure selection, enabling better‑balanced, high‑performance applications.

Javamemory optimizationRedisData StructuresQuicklistListpack
JavaEdge
Written by

JavaEdge

First‑line development experience at multiple leading tech firms; now a software architect at a Shanghai state‑owned enterprise and founder of Programming Yanxuan. Nearly 300k followers online; expertise in distributed system design, AIGC application development, and quantitative finance investing.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.