Concept lesson · Foundations
Probabilistic data structures
Start here
Definition
Probabilistic data structures use randomization, often through hashing, to obtain useful space or performance tradeoffs. This chapter focuses on compact approximate summaries with stated error models: Bloom filters for membership, HyperLogLog for distinct counts, and Count-Min Sketch for frequencies.
Why it matters: Keeping every item in fast memory or checking a database for every query can be expensive; a summary can reduce that work when its possible errors are acceptable.
Each inserted key sets several bits. If any queried bit is zero, the key was not inserted. All ones can still be a collision.
Read the diagram step by step
- Insert A with hash positions {2,7}, then B with {7,12}. Set bits 2,7 and 12.
- Query C at {2,12}: both are one, yet C was never inserted. This is a false positive, so check the real store.
- Query D at {1,12}: bit 1 is zero, so D is definitely absent under the insertion-only contract.
- An ordinary Bloom filter has no false negatives for inserted keys, but deleting bits can break that property.
Worked example
A sets Bloom-filter bits 2 and 7; B sets 7 and 12. C tests bits 2 and 12 and gets “possibly present” although C was never inserted. An exact lookup must resolve that positive.
Key takeaways
- Bloom says definitely absent or possibly present under its correct coverage assumptions.
- HyperLogLog answers how many distinct items, not whether a particular item exists.
- Count-Min estimates a supplied key’s frequency; its insert-only errors overestimate.
You will learn to
- Trace Bloom-filter bits and explain the exact false-positive and false-negative assumptions.
- Estimate filter memory and saved membership reads using an assumed workload.
- Choose Bloom, HyperLogLog, or Count-Min Sketch according to the question and acceptable error.
Practice in this chapter
8 interview questions with model answers and follow-ups.
Go to interview practiceUseful foundations: Capacity estimation: throughput, latency, concurrency and storage · Caching: cache hits, misses, write policies and invalidation · Storage engines and data models
Workload and timing examples are interview assumptions.
Dotted concept links open the relevant explanation in a new tab.
01Probabilistic data structures: definition and error models
A probabilistic data structure uses randomization, often through hashing, to obtain useful space or performance tradeoffs. The broader category also includes randomized exact structures, such as skip lists; probabilistic does not always mean an approximate answer. This chapter focuses on compact approximate summaries with stated error models. A Bloom filter approximates set membership, HyperLogLog estimates the number of distinct items, and Count-Min Sketch estimates how often a supplied item occurs. These summaries save memory or work by discarding information. The engineering task is to know which mistakes are possible and place each summary where those mistakes are acceptable.
Use approximate structures where their error model is acceptable, using exact records and checks for decisions that cannot safely be reversed. The worked crawler calculation assumes one million stored normalized URLs and 100,000 membership checks, of which 80% concern absent URLs. These inputs are illustrative assumptions. The exact URL database remains responsible for unique discovery and scheduling.
An in-memory hash set can answer membership exactly, but storing every full URL and its indexing overhead may consume too much memory. A database lookup for every candidate can also be expensive. A Bloom filter can cheaply rule out many absent candidates. It does not store the URLs themselves, prove that a page was fetched successfully, or replace the exact claim that prevents two workers from scheduling the same URL.
02Bloom filter: bit array, hashes, and false positives
A Bloom filter is a bit array plus several hash functions. A hash function maps an item to a position in that array. To insert a URL, set its positions to one. To test a URL, inspect those positions: any zero proves it was not inserted into this filter; all ones mean only “possibly present.”
The small bit array illustrates the mechanism, not a recommended production size. A standard correctly maintained Bloom filter has false positives but no false negatives for inserted items.
Remember: One zero proves absence; all ones require an exact check.
Read the diagram
- Only X has been inserted; positions 1, 4 and 6 are set to one.
- Y checks 0, 4 and 6. Bit 0 is zero, so Y is absent when the filter covers every stored key.
- Z checks 1, 4 and 6: all one, so the filter says possibly present.
- The exact store says Z is absent: the shared bits produced a false positive.
Try from memoryWhy can we not delete X by simply clearing its bits?
Other inserted keys can share those bits. Clearing them can make a present key look absent.
Use a tiny sixteen-bit filter and two illustrative hashes. Initially every bit is zero.
| URL | Hash positions | Action or answer |
|---|---|---|
| A | 2 and 7 | Insert: set bits 2 and 7 |
| B | 7 and 12 | Insert: set bit 12; bit 7 was already set |
| C | 2 and 12 | Both are one: possibly present, although C was never inserted |
| D | 1 and 12 | Bit 1 is zero: definitely not inserted |
C is a false positive created by shared bits. A and B remain discoverable because insertion never clears their positions. “No false negatives” relies on correct insertion, intact state, consistent hashing, and the filter representing the set being queried. It is not a promise about a stale or partially rebuilt copy of the database.
03Bloom filter with an exact membership database
With the assumed 1% false-positive rate, 80,000 absent queries cause about 800 false positives. The 20,000 present queries also require exact verification. Expected membership reads therefore fall from 100,000 to about 20,800, saving about 79,200. These figures concern preliminary reads, not all database operations: durable inserts and claim checks remain.
If a URL is in the database but missing from the filter, the filter can wrongly report it absent. An atomic database claim can still prevent duplicate scheduling. A design that trusts the filter’s negative result without that check cannot. Record which data the filter covers and what changes a rebuild includes.
- 1 → 3insertURL A → bits 2,7 → Bits 2,7,12 are set
- 2 → 3insertURL B → bits 7,12 → Bits 2,7,12 are set
- 3 → 5both queried bits setBits 2,7,12 are set → Maybe present
- 4 → 5testURL C → bits 2,12 → Maybe present
- 5 → 6verify positiveMaybe present → Exact set: C absent
04Bloom filter sizing: bits, hashes, and false-positive rate
Sizing starts with how many distinct URLs the filter must cover and how many unnecessary exact lookups are acceptable. From that expected population and target false-positive rate, choose the number of stored bits and hash positions. The formulas below quantify the memory-versus-error tradeoff under their hashing assumptions.
For an idealized Bloom filter with good hashing, expected false-positive probability is approximately p ≈ (1 − e^(−kn/m))^k, where m is bits, n inserted distinct items, and k hash positions per item. Here e is approximately 2.718, and ln denotes the natural logarithm. Near the optimal hash count, useful sizing formulas are m ≈ −n ln(p)/(ln 2)^2 and k ≈ (m/n) ln 2.
For n = 1,000,000 and p = 0.01, this gives about 9.59 million bits, or 1.20 MB using decimal units, with approximately seven hashes. That excludes object headers, alignment, and implementation overhead. It is roughly 9.6 bits per stored URL, regardless of the URL’s length, because the filter does not retain the original text.
Exceeding the planned population sets more bits and raises the false-positive rate. It does not suddenly start forgetting inserted items, but its ability to reject absent queries deteriorates. Capacity and hash quality must be monitored. A smaller error target costs memory and hash work; choose it using the database work saved, not a habit of demanding the smallest possible percentage.
05Bloom filter deletion, rebuilds, and coverage
For an append-only visited-URL set, an append-only filter rebuilt periodically is simpler. A rebuild must cover a consistent source snapshot plus changes made during construction, or queries must use a safe bypass while coverage is incomplete. On a crash or corrupt filter, fall back to the exact store until a valid filter is available. A performance accelerator should fail into additional work rather than permanent omissions.
If visited URLs expire, define which time period each filter covers or use a supported deletion method. Rotating filters changes the set that membership answers describe. Bitwise OR combines compatible filters into a union, but representing more URLs raises the false-positive rate.
Concurrency is another correctness assumption. Two unsynchronized read-modify-write updates to the same bit-array word can overwrite each other even when each worker only intends to set bits. Use the implementation's supported atomic updates or synchronization. The same care applies to counting-filter increments and decrements; an accelerator implemented with lost updates can violate its advertised error direction.
06HyperLogLog and Count-Min Sketch
Distinct-count estimation is a separate query from membership. A HyperLogLog sketch estimates how many distinct URLs occurred. Each register is a small stored number. Some leading hash bits select a register; in the remaining bits, count leading zeros plus one and retain that register’s largest observed count. In a toy four-register setup, 01 | 0001... selects the register numbered 1 and contributes 4. A later 01 | 01... contributes 2, so the register stays 4. Long zero runs become more likely as more distinct items arrive. HyperLogLog combines all registers using a calibrated estimator, rather than treating one rare hash as an exact count. Repeating the same URL does not represent another distinct item. It cannot answer whether C was present or list the discovered URLs.
Different randomized hash assignments can produce different estimates for the same true distinct count. Relative standard error describes the statistical spread of those estimates relative to that count. More registers reduce that spread at the cost of more memory.
A Count-Min Sketch answers approximate frequency questions, such as how often host H appeared. It uses several rows of counters, each with its own hash selecting one column. Each occurrence increments one counter per row; querying that key returns the minimum of those same counters. In an insert-only stream with nonnegative increments, collisions can overestimate a frequency but do not make that estimate smaller than the actual count. If H occurred twenty times and its counters are 27, 23 and 22, the estimate is 22. Hash collisions explain the extra two; the sketch does not identify the colliding hosts.
For Count-Min, width is the number of counters in each row and depth is the number of independently hashed rows. More columns reduce collisions; additional rows make it less likely that every row badly overestimates the same key. The error target determines these two memory costs.
The standard Count-Min dimensions make the tradeoff concrete: choose width ceil(e / epsilon) and depth ceil(ln(1 / delta)). For a fixed queried key in a nonnegative stream, suitable independent hashes give an estimate between its true count f and f + epsilon * N with probability at least 1 - delta, where N is the sum of all increments across the stream. epsilon sets the allowed additive error as a fraction of N; delta is the maximum failure probability for that bound. ceil(x) is the smallest integer greater than or equal to x, so an integer stays unchanged. ln is the natural logarithm, and e ≈ 2.71828; use the unrounded constant when calculating the width. With epsilon = 0.001, delta = 0.01 and N = 1,000,000, width 2,719 and depth 5 use 13,595 counters. The promised additive error can still be 1,000, which is large for a host seen only twenty times. This is not a simultaneous guarantee for every adaptively chosen key; counter overflow or unsupported signed updates also invalidate the simple bound.
07Bloom filter, HyperLogLog, and Count-Min comparison
| Structure | Crawler question | What it cannot provide |
|---|---|---|
| Bloom filter | Might this URL be in the visited set? | Exact positive membership or item retrieval |
| HyperLogLog | About how many distinct URLs were observed? | Membership, full enumeration, exact billing counts |
| Count-Min Sketch | About how often was host H observed? | Exact frequency or a list of heavy keys by itself |
Count-Min’s additive error is related to total stream volume under its stated probabilistic bounds, so a small relative error for the whole stream can be large for a rare host. Finding heavy hosts also needs candidate tracking. Compatible sketches can merge—HyperLogLog by register maxima and Count-Min by counter sums—but parameters, hash conventions, and event semantics must match.
In an interview I would say: “The Bloom filter can avoid a preliminary database read when a URL is definitely absent from the covered set. The database’s unique insert still prevents two workers from scheduling the same URL. HyperLogLog drives approximate distinct-count dashboards, and Count-Min helps identify frequency candidates. None is the authoritative record for a decision where an approximate answer can silently lose work.”
Practise the interview questions
Say your answer aloud before opening the model answer. Then answer the follow-up and compare the reasoning.
What is a probabilistic data structure? Use a Bloom filter to explain its possible error.
Reveal a model answer
It uses randomization to obtain a useful space or performance tradeoff. Some probabilistic structures answer exactly; the Bloom filter is an approximate membership summary with a defined error model. In the Bloom example, A sets bits 2 and 7 and B sets 7 and 12. C tests 2 and 12, so the filter says possibly present even though C was never inserted: a false positive. It no longer knows which item set each bit.
Interviewer follow-up
What should a crawler do with that positive result?
Reveal the follow-up answer
Check the exact URL set. Skipping C solely because of a Bloom positive can permanently omit a new page. A negative saves a preliminary lookup only under the filter’s coverage assumptions; the exact unique insert still handles concurrent claims.
What the answer must demonstrate: Name the supported question, error direction, and business consequence.
Under what coverage and update assumptions is a Bloom-filter negative safe to trust?
Reveal a model answer
“It proves absence from a correctly maintained filter’s inserted set. To infer absence from the database, the filter must cover that database state. A stale or interrupted rebuild may omit real entries.”
Interviewer follow-up
How do you survive an incomplete filter?
Reveal the follow-up answer
“Bypass the filter, or trust it only for data its coverage record proves complete. Keep the exact atomic database claim when scheduling a URL.”
What the answer must demonstrate: State which set the guarantee describes.
Estimate memory for one million URLs at 1% false positives.
Reveal a model answer
“Using the standard idealized formulas, I need about 9.59 million bits, or 1.20 decimal MB, and about seven hash positions per item. I would add implementation overhead and headroom for growth.”
Interviewer follow-up
What happens at two million entries without resizing?
Reveal the follow-up answer
“More bits are set and false positives rise; the original 1% target no longer holds.”
What the answer must demonstrate: Keep bits and bytes distinct and acknowledge the sizing assumptions.
Of 100,000 membership checks, 80% are absent. With a 1% Bloom false-positive rate, how many exact preliminary reads remain?
Reveal a model answer
“Of 100,000 checks, 80,000 are absent. At a 1% false-positive rate about 800 absent checks still reach the database, alongside 20,000 present checks. That is about 20,800 reads instead of 100,000.”
Interviewer follow-up
Does it save the new URL’s durable insert too?
Reveal the follow-up answer
“No. It removes a preliminary read, while the exact claim or insert remains necessary.”
What the answer must demonstrate: Do not confuse lookup reduction with eliminating all authoritative work.
Bloom key A sets bits 2 and 7; B sets 7 and 12. Why can deleting A not simply clear its bits?
Reveal a model answer
“B shares bit 7, so clearing it can turn B into a false negative. Ordinary Bloom bits do not record ownership. I need a correctly managed counting variant or a rebuild/epoch policy.”
Interviewer follow-up
Can a counting filter delete any item that tests positive?
Reveal the follow-up answer
“No. A positive may itself be false, so decrementing for a never-inserted item can damage other entries. Deletions require reliable membership and accounting.”
What the answer must demonstrate: Deletion changes the guarantee unless ownership is accounted for.
Could HyperLogLog replace the visited-URL set?
Reveal a model answer
“No. HyperLogLog estimates distinct cardinality; it cannot answer whether a particular URL was seen or enumerate URLs. It is useful for aggregate crawler statistics, while exact claim decisions need an exact set or database.”
Interviewer follow-up
Is 0.81% a maximum error at 16,384 registers?
Reveal the follow-up answer
“No. It is an approximate relative standard error from the classic analysis, not a deterministic per-answer bound.”
What the answer must demonstrate: Separate an aggregate estimator from a membership structure.
Why does Count-Min take the smallest counter?
Reveal a model answer
“Each counter contains the item’s own increments plus collisions. Under nonnegative insert-only updates, taking the minimum reduces collision inflation without dropping below the true count. In the example, min(27,23,22) estimates a true count of twenty as twenty-two.”
Interviewer follow-up
Can it list the busiest hosts by itself?
Reveal the follow-up answer
No. It answers estimates for supplied keys; heavy-key discovery needs candidate tracking. Also inspect the additive bound against total stream volume: epsilon = 0.001 at one million increments allows error of 1,000 for a fixed key, which can swamp a rare count.
What the answer must demonstrate: Qualify the update model and distinguish estimation from enumeration.
Can two crawler workers merge their sketches?
Reveal a model answer
“Yes, when the sketch types, dimensions, hash functions and item normalization are compatible. Bloom union uses OR; HyperLogLog uses register maxima; Count-Min sums counters.”
Interviewer follow-up
What could still make the merged answer misleading?
Reveal the follow-up answer
“Different URL normalization or duplicate event delivery changes the represented data. HLL counts distinct identities while Count-Min counts occurrences, so their response to replay differs.”
What the answer must demonstrate: Compatible arrays are not enough; semantics must match.
Blank-page exercise · 15 minutes
Build the answer yourself
Design a crawler’s visited-URL accelerator for one million stored URLs and a 1% Bloom false-positive target. Explain what happens for a positive, a negative, a filter crash, and two workers discovering the same URL.
- Compute approximate bits and hash count, with units.
- Trace one false positive using shared bit positions.
- Keep the exact claim or uniqueness check for concurrent scheduling.
- Choose a separate structure for distinct URL count and per-host frequency.
Check that each component and design decision follows from your requirements and workload.
Recall the key ideas
Answer from memory before opening each card. Explain why the choice works and what it costs. Revisit missed cards tomorrow.
Probabilistic data structuresWhat does a Bloom positive mean?Recall first, then reveal
Every tested position is set; another combination of inserted items may have set them. Verify when correctness requires exact membership.
Positive = possible
Return to lessonProbabilistic data structuresWhat does “no false negatives” assume?Recall first, then reveal
A valid filter covering the queried set, correct insertions and hashing, and no unsafe deletion or state loss.
Trust absence only for the set the filter covers.
Return to lessonProbabilistic data structuresWhich sketch answers which question?Recall first, then reveal
Bloom: membership maybe. HyperLogLog: distinct count. Count-Min: frequency estimate.
Membership → distinct count → frequency.
Return to lessonProbabilistic data structuresCan a Bloom negative prevent two simultaneous inserts?Recall first, then reveal
No. Both workers may see absence; an exact atomic claim or uniqueness rule resolves the race.
A filter is not a lock
Return to lessonFinal revision
Summary and interview notes
An approximate summary is useful only when its supported question and error model match the decision. Use exact records and atomic uniqueness checks when deciding who may perform an irreversible action; use compact summaries to reduce reads or power explicitly approximate aggregates.
Remember these points
- A valid Bloom negative proves absence only from the filter’s covered inserted set; a positive requires verification for exact membership.
- One million items at a 1% Bloom target needs roughly 9.59 million bits and seven hashes, before overhead.
- HyperLogLog estimates distinct count; its typical standard error is not a worst-case per-answer limit.
- Insert-only Count-Min estimates a supplied key’s frequency from above, with additive error tied to total stream volume.
- Merge only sketches with compatible hashing and matching definitions of their observations. Do not add the same frequency snapshot twice.
Interview tips
- State the error direction and the business consequence before recommending a sketch.
- Calculate saved authoritative reads separately from inserts and atomic claim checks.
- Test incomplete rebuilds, concurrent updates and replay, not just ideal hash collisions.
Important qualifications
- A standard Bloom filter cannot safely delete by clearing shared bits; counting variants need reliable membership and counter accounting.
- Statistical error formulas assume the stated hashing and update model; implementation races and overflow are not covered by those formulas.
Technical references
- Bloom: Space/Time Trade-offs in Hash Coding with Allowable ErrorsPrimary paper introducing the membership filter and the space/error tradeoff.
- Apache Commons Collections: Bloom Filters, an IntroductionOfficial implementation documentation for sizing relationships and filter behavior.
- Flajolet et al.: HyperLogLogPrimary analysis of approximate distinct counting and its typical relative standard error.
- Cormode and Muthukrishnan: Count-Min SketchAuthor-hosted primary paper on approximate frequency summaries; replaces an unavailable older Rutgers URL. All crawler numbers and tiny hashes here are constructed examples.
- William Pugh: Skip Lists — A Probabilistic Alternative to Balanced TreesPrimary paper on randomized balancing for exact dictionary operations. Establishes the broader meaning of probabilistic data structures; this chapter focuses on approximate summaries.
Practice marks stay in this browser.