🌸 Bloom Filters & Probabilistic Structures¶
Explain in 2 min
Probabilistic data structures trade a little accuracy for a huge memory win. A bloom filter answers set membership as "definitely not present" or "possibly present" - never a false negative - in a tiny bit array, so you use it as a cheap pre-check before an expensive lookup (disk, DB). A count-min sketch estimates how many times it's seen an item (frequency) in fixed memory, overcounting a little. HyperLogLog estimates how many distinct items there are (cardinality) in kilobytes even for billions of items. The theme: when exact answers cost too much memory, an approximate answer with a known error bound is often good enough.
Bloom filter [advanced]¶
A bit array + k hash functions. To add an item, hash it k ways and set those k bits. To check, hash it k ways and see if all k bits are set: - All set → possibly present (could be a false positive - other items set those bits). - Any unset → definitely not present (no false negatives).
add(x): FOR i in 1..k: bits[h_i(x) % m] = 1
contains(x): FOR i in 1..k: IF bits[h_i(x) % m] == 0: RETURN "no"
RETURN "maybe"
- No false negatives, tunable false-positive rate (more bits + optimal k → fewer).
- Can't delete from a standard bloom filter (clearing a bit could break other items) - a counting bloom filter uses small counters instead of bits to allow deletion.
When to use: a cheap gate before an expensive operation. Examples: LSM-tree/SSTable "does this key exist here?" (skip the disk read if not) - see Database Internals; "have I seen this URL?" in a web crawler; "is this username taken?" pre-check. Built on hash functions - see Hashing.
Count-min sketch [advanced]¶
Estimates frequency of items in a stream using a small 2-D array of counters and k hash functions. To add, increment one counter per row; to query, take the minimum across the rows (minimizing the effect of collisions). It overcounts (never undercounts), with a bounded error.
When to use: "top-k / heavy hitters" and approximate counts at stream scale where an exact per-item counter map won't fit - trending terms, per-key traffic, rate stats.
HyperLogLog [advanced]¶
Estimates cardinality (number of distinct items) using a few KB regardless of set size, by observing the maximum run of leading zeros in item hashes (rare long runs imply many distinct items). Typical error ~1-2%.
When to use: "how many unique visitors / unique search terms / distinct IPs" over billions of
events, where storing every distinct item is infeasible. Redis PFADD/PFCOUNT is HyperLogLog.
Choosing a structure¶
| Question | Structure | Error mode |
|---|---|---|
| Is x in the set? | Bloom filter | false positives only |
| How many times has x appeared? | Count-min sketch | overcounts |
| How many distinct items? | HyperLogLog | ~1-2% off |
| Exact, small set | plain hash set/map | none (but O(n) memory) |
Reach for these only when the exact structure won't fit in memory - an approximate answer with a known error bound beats an out-of-memory failure.
Common interview traps¶
- Claiming a bloom filter can give false negatives - it cannot; only false positives.
- Trying to delete from a standard bloom filter (use a counting bloom filter).
- Confusing frequency (count-min) with cardinality (HyperLogLog) - different questions.
- Using them when an exact set fits fine - added complexity for no benefit.
Related¶
- Q&A drills: Hashing Q&A
- Hash functions (the building block) → Hashing
- SSTable/LSM use of bloom filters → Database Internals
- Web crawler "seen URL" filter → Web Crawler