How to Identify and Eliminate Redis BigKey Bottlenecks
This article explains what constitutes a Redis BigKey, why oversized keys degrade performance through data skew, network blocking, slow queries and CPU pressure, and provides practical detection methods, open‑source tooling, and mitigation techniques such as lazy‑free deletion, incremental scans, and key sharding.
Background
In JD Daojia's shopping‑cart service each user stores items per store in a Redis HASH. When a single store accumulates many items or a user accesses many stores, the hash key grows large and degrades online performance.
Definition of a BigKey
A key is considered a BigKey when either its value size or element count exceeds typical thresholds:
String : value > 10 KB.
Non‑string structures (HASH, SET, ZSET, LIST) : number of elements ≥ 10 000 or total size ≥ 100 KB.
Cluster‑wide : total number of keys > 100 million.
Typical causes are inappropriate data structures, lack of size estimation, and missing expiration.
Impact of BigKeys
BigKeys create data skew and network blocking. Accessing a large key forces the responsible shard to consume extra CPU, bandwidth and memory, which can increase latency for all keys on that shard and raise overall CPU load, especially during persistence (fork) operations.
Detecting BigKeys
redis-cli --bigkeys
$ redis-cli --bigkeys
# Scans the whole keyspace, gathers type and size, and prints the biggest key per type.The command iterates with SCAN, obtains each key’s type via TYPE, measures size with the appropriate command ( STRLEN, HLEN, SCARD, etc.), and updates per‑type statistics.
Key parts of the implementation
typedef struct {
char *name; // data type name (string, list, …)
char *sizecmd; // command used to obtain size
char *sizeunit; // unit for reporting (bytes or elements)
unsigned long long biggest; // size of the biggest key of this type
unsigned long long count; // total number of keys of this type
unsigned long long totalsize; // aggregate size of all keys of this type
sds biggest_key; // key name of the biggest key
} typeinfo;The algorithm creates a typeinfo entry for each of the six Redis data types, then repeatedly:
Calls SCAN to fetch a batch of key names.
Uses TYPE to discover each key’s data type.
Executes the appropriate size command to obtain the key’s size.
Updates the typeinfo record if the current key is larger than the previously recorded biggest key.
Accumulates total size and count for later summary output.
After the scan finishes, the tool prints a summary of sampled keys, total key‑name length, the biggest key per type, and per‑type averages.
Open‑source offline analysis
The redis‑rdb‑tools project (https://github.com/sripathikrishnan/redis-rdb-tools) can parse RDB snapshots to locate large keys without touching a live instance. It is useful for post‑mortem analysis but does not provide real‑time metrics.
Mitigation Strategies
Prevention
Assign staggered TTL values so that expirations are spread over time.
Store JSON payloads as plain strings and prune unused fields before caching.
Compress large values when appropriate (e.g., gzip the JSON string).
Enforce business limits such as maximum number of stores per user or maximum items per store.
Deletion Methods
DEL (synchronous): In Redis < 4.0 the command blocks the main thread while freeing memory.
UNLINK (lazy‑free, async): Introduced in Redis 4.0; controlled by lazyfree‑lazy‑user‑del and related settings. Large objects are freed in a background thread.
SCAN + incremental delete : Iterate over keys in small batches and delete them gradually to avoid long blocking periods.
Internally Redis decides between dbSyncDelete and dbAsyncDelete based on the estimated free‑effort. Objects whose free‑effort exceeds LAZYFREE_THRESHOLD (64) and have a reference count of 1 are freed asynchronously via freeObjAsync.
Divide‑and‑Conquer
Split a huge string into multiple keys and retrieve them with pipelined GET or MGET.
Shard large collections across multiple keys (e.g., hash‑field hashing: HGET user:store:1 field where the field name is hashed to one of N sub‑hashes).
Move massive keys to an alternative storage system (e.g., a relational database or object store) and keep only a reference in Redis.
Conclusion
By limiting the number of stores per user, capping items per store, and redesigning the Redis schema (e.g., using per‑store LIST or sharded HASH keys), the BigKey problem in the shopping‑cart service can be mitigated without service disruption.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
JD Retail Technology
Official platform of JD Retail Technology, delivering insightful R&D news and a deep look into the lives and work of technologists.
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.
