Streaming Algorithms and Sketches
Learning Objectives
- Describe the streaming model: one pass over a sequence too large to store, with memory polylogarithmic in its length, and explain why exact answers are often impossible in it.
- Explain the Count-Min sketch, prove that its estimates never undercount and overcount by at most with probability , and size it from and .
- Explain the idea behind HyperLogLog's distinct-count estimate (leading zeros of hashed values) and its standard error .
- Connect sketches to Bloom filters as members of the same family of small, mergeable, probabilistic summaries.
Context & Motivation
A network router sees billions of packets per hour and must report which source addresses send the most traffic. An analytics service must count unique visitors per day across hundreds of servers. A database planner must estimate how many distinct values a column has without scanning it twice. In each case the data stream is far larger than memory, often cannot be stored at all, and arrives once.
algorithms-software/data-structures-ii met the Bloom filter, which answers set-membership questions in a few bits per element by accepting a controlled false-positive rate. Streaming algorithms generalize that bargain: in one pass and with memory polylogarithmic in the stream length, compute a small summary, a sketch, from which approximate answers can be read with provable error bounds. Most interesting exact statistics (the number of distinct elements, the exact most frequent item) provably require memory linear in the stream, so approximation and randomness are not optional. Stanford's CS168 and MIT's 6.854 treat Count-Min and distinct-element estimation as core tools; HyperLogLog, from Flajolet and colleagues (2007), runs inside Redis, BigQuery, and Presto.
Core Theory
The model
A stream is a sequence of items from a universe of size . The algorithm reads each item once, in order, and keeps memory . The frequency of item is , the number of times it appears, and .
Count-Min sketch: frequency estimation
Keep a table of rows and columns of counters, all zero, and independent hash functions from a pairwise-independent family, each mapping items to .
- Update (item arrives): for each row , increment .
- Query (estimate ): return .
Every counter touches includes all of 's own occurrences, so : the sketch never undercounts. Errors come from other items hashing to the same counter. In one row, the expected extra count is at most , since each other item collides with probability . By Markov's inequality, the extra count exceeds with probability at most . Rows are independent, so the minimum exceeds that only if every row does:
Choosing and gives with probability at least , using counters, independent of the universe size. Two sketches built with the same hash functions merge by adding their tables, so each server can sketch its own traffic and a coordinator combines them.
The error is relative to , the whole stream, so Count-Min is accurate for heavy hitters (items with much larger than ) and useless for rare items, whose true counts are swamped by the additive error.
Counting distinct elements
The number of distinct items cannot be computed exactly in sublinear space, but a remarkably small sketch estimates it. Hash every item to a uniformly random bit string. Among distinct items, about half the hashes start with 0, a quarter with 00, and in general a fraction start with zeros. So if the longest run of leading zeros seen is , then is plausibly around . Repeated items hash identically, so duplicates do not affect the statistic: the sketch counts distinct items automatically.
A single maximum is a very noisy estimator. HyperLogLog splits the stream into buckets using the first bits of each hash, keeps the maximum leading-zero count in each bucket (a few bits each), and combines them with a harmonic mean:
where corrects a systematic bias. Its standard error is about . With registers of 6 bits each, about 12 KB, the error is about 0.8%, whether the stream has a thousand or a billion distinct items. HyperLogLog sketches also merge, by taking the register-wise maximum.
Worked Examples
Example 1: sizing a Count-Min sketch
Problem: A router processes packets per hour and must estimate per-source counts within (0.1% of traffic), with failure probability per query. How large is the sketch?
Trace: columns and rows, so counters. With 4-byte counters, about 54 KB. An exact table of counts for every IPv4 source could need billions of entries. Any source sending more than about packets will show an estimate clearly above the error band, so the heavy hitters are identified reliably, while a source with 100 packets may be reported as anything up to about .
Example 2: the leading-zeros intuition
Problem: A stream has some unknown number of distinct items. After hashing, the longest run of leading zeros observed among all hashes is 20. What does a single-register estimate suggest, and why is HyperLogLog needed?
Resolution: A hash starting with 20 zeros occurs with probability , so seeing one suggests roughly distinct items. But a single lucky hash with a few extra zeros doubles the estimate per extra zero: seeing 21 zeros would suggest . The variance of one register is huge. Splitting into buckets, each seeing about items, and averaging harmonically (which damps the influence of unusually large registers) brings the standard error down to , using about 3 KB.
Common Misconceptions & Pitfalls
- "A sketch is just sampling." Sampling misses rare items and needs to know in advance to choose a rate; sketches touch every item and give deterministic one-sided guarantees (Count-Min never undercounts) or tight relative errors (HyperLogLog), and they merge across machines exactly.
- "Count-Min gives accurate counts for every item." Its error is additive in . For items with small true counts, the relative error can be enormous; use it for heavy hitters, or switch to variants such as Count-Sketch when error relative to the second moment is needed.
- "HyperLogLog needs a cryptographic hash." It needs a hash that behaves uniformly on the data; fast non-cryptographic hashes are standard. What matters is consistency: every sketch to be merged must use the same hash function.
Summary
Streaming algorithms read data once, in order, with memory polylogarithmic in its size, and many exact statistics are impossible in that model, so they return approximate answers with provable error bounds. The Count-Min sketch hashes each item into one counter per row and estimates a frequency by the minimum over rows; it never undercounts, overcounts by at most with probability using counters, and suits heavy hitters. HyperLogLog estimates the number of distinct items from the maximum leading-zero counts of hashed values across buckets, with standard error in a few kilobytes. Both merge across machines. The next concept moves from algorithms to complexity, asking what can be decided when memory, not time, is the scarce resource.