Finding the Top K (The "Trending" Problem)
In a stream of 1 Billion events, how do you find the 10 most frequent items using only 100MB of RAM? This is a useful model for trend detection, query-frequency analysis, and traffic-abuse detection. It is not a description of any named company's private ranking system.
1. Requirements
- Input: A never-ending stream of strings (queries, IPs, hashtags).
- Output: The top 10 most frequent items in the last X minutes.
- Constraint: You cannot store every item. (10B items * 100 Bytes = 1TB RAM).
2. Approach 1: Batch Processing (MapReduce)
If we don't need real-time, we can use a distributed file system.
- Split: Divide logs into 100 files.
- Map: Emit
(Key, 1)for every occurrence. - Shuffle: Group by Key.
(Key, [1, 1, 1, 1]). - Reduce: Sum the lists.
(Key, Total). - Sort: Sort by Total and take Top 10.
- Con: High latency. Takes minutes/hours.
3. Approach 2: Streaming with Hash Map
Store HashMap<String, Integer>.
- Problem: In the "Long Tail" of the internet, there are billions of unique keys that appear once. Storing them fills up memory instantly.
4. Approach 3: Probabilistic Data Structures (Count-Min Sketch)
A Count-Min Sketch is a 2D array that trades accuracy for space. It is the "Bloom Filter" of counting.
Structure
- Matrix: A
Width x Deptharray of counters (e.g., 1000 x 5). Use 0 as initial value. - Hash Functions: 5 different hash functions ().
Algorithm
- Add(Item):
- Calculate row indices:
- Increment
Matrix[0][r1],Matrix[1][r2]...
- Estimate(Item):
- Get values at all 5 positions.
- Return the Minimum of these values.
- Why Min? Because collisions only add to the count. The true count cannot be higher than the minimum observed value.
Space Efficiency
For nonnegative increments, a Count-Min Sketch overestimates frequencies. Width controls the additive error bound; depth controls the probability of exceeding that bound. Error is relative to total stream weight, so rare items may have large relative errors. A sketch cannot enumerate keys; keep a separate candidate set or use a heavy-hitter structure.
5. Sliding Windows
"Trending" means "Popular Right Now", not "Popular since 2010". We need to forget old data.
- Time Slicing:
- Create a CMS (Count-Min Sketch) for Minute 1, Minute 2, Minute 3.
- To approximate "Last 5 mins", sum compatible sketches with identical dimensions and hashes. Bucket boundaries make this an approximate window unless partial buckets are handled.
- Exponential Decay:
- Multiply all counters by 0.9 every minute. Old values fade away.
6. An illustrative trend-detection architecture
- Ingestion: Tweets enter Kafka.
- Processor: Apache Flink / Spark Streaming workers read the stream.
- Aggregation:
- Workers maintain a local Count-Min Sketch in memory.
- Every 10 seconds, flush the Top 100 candidates to a central Redis.
- Storage: Redis Sorted Set (
ZSET).ZINCRBY trending 1 "#systemdesign"
- API:
ZRANGE trending 0 9 REV WITHSCORESreturns the highest scores in the stored candidate set. Local top-100 truncation can omit a globally important key, so validate candidate recall.
Summary
- Exact Count: Needs storage proportional to distinct keys unless the key universe is bounded; external storage is another option.
- Count-Min Sketch: For chosen width and depth, memory stays fixed as the stream grows; updates visit every row. Accuracy depends on those parameters and stream weight.
- Lossy Counting: Another popular algorithm for this problem.
Sources and verification
Redis Count-Min Sketch documentation explains dimensions and error. For a design exercise, feed a burst of a previously unseen key near a window boundary: measure candidate recall, overcount, and expiry lag separately. Exponential decay produces a weighted history, not an exact time window.
Keep reading
Geohashing (Location Encoding)
A geocoding system that encodes latitude/longitude coordinates into short alphanumeric strings for efficient proximity searches and spatial indexing.
HyperLogLog (Cardinality Estimation)
A probabilistic algorithm for counting unique items in massive datasets using minimal memory, with tunable statistical error and compact mergeable state.
MapReduce
A programming model for processing massive datasets in parallel across distributed clusters. Understanding Map, Shuffle, Reduce with real-world use cases from Google, Hadoop, and Spark.
Raft Consensus Algorithm
A comprehensive guide to Raft, the consensus algorithm powering Etcd, Consul, and Kubernetes. Leader election, log replication, safety guarantees, and production deployment patterns.
Token Bucket vs Leaky Bucket
A comprehensive comparison of two fundamental rate limiting algorithms: Token Bucket allows controlled bursts while Leaky Bucket enforces constant output rates.
Video Streaming: CDN Capacity and Playback Recovery
Separate documented Open Connect facts from a worked streaming design, with bandwidth estimates, adaptive bitrate decisions and outage scenarios.