Qm
Core

Bloom Filters

A compact data structure that answers "have I seen this before?" using a fraction of the memory a full set would need, at the cost of occasionally saying yes when the answer is actually no.

Prerequisites: Hash Maps and Sets

A market-data cache needs to check, millions of times a second, whether a given order ID has already been processed, but storing every order ID ever seen, forever, in a hash set eats memory that grows without bound. A Bloom filter answers "have I definitely not seen this, or possibly seen this?" using a fixed, small block of memory, trading a small, tunable false-positive rate for that saved space.

A Bloom filter is a bit array plus several hash functions. Adding an item flips several bits to 1; checking an item asks whether those same bits are all 1. It can never wrongly say "no", only, occasionally, wrongly say "yes."

How it works

Start with a bit array of size mm, all zeros, and kk independent hash functions, each mapping an item to a position in that array.

To add an item: compute its kk hash values, and set the bit at each of those kk positions to 1.

To check an item: compute the same kk hash values. If any of those bits is 0, the item was definitely never added, a bit that's still 0 could only mean nothing ever touched it. If all kk bits are 1, the item is probably in the set, but those bits could have all been set by other items' overlapping hashes, so it might be a false positive.

bit array (16 slots) order A (blue) sets bits 1, 4, 8 order B (amber) sets bits 2, 6, 12 query "order C" (red) checks bits 4, 6, 8, all already 1 filter says "probably seen", but C was never added
Two real inserts happen to cover all three bits a third, never-inserted item hashes to, a false positive. False negatives are impossible; false positives are the price of the compression.

Worked example

Take m=100m = 100 bits and k=3k = 3 hash functions, with 10 items already inserted. The fraction of bits still 0 is about ekn/m=e0.374%e^{-kn/m} = e^{-0.3} \approx 74\%. The false-positive rate, probability all kk bits for a never-inserted item are 1, is roughly (1ekn/m)k(0.26)31.7%(1 - e^{-kn/m})^k \approx (0.26)^3 \approx 1.7\%. Doubling mm to 200 bits drops that to about 0.34%0.34\%: more bits, fewer accidental collisions.

What this means in practice

Bloom filters guard expensive lookups: a database checks one before touching disk to see if a key might exist, LevelDB and Cassandra use them to skip SSTables that can't contain a queried key, and a trading system might use one to filter "have I already routed this order ID" before a slower, authoritative check. The false-positive rate is tunable via mm and kk; no tuning removes it entirely, only shrinks it.

A Bloom filter cannot delete items, flipping a bit back to 0 could unset a bit another item also relies on, silently turning a true "yes" into a false "no," which breaks the one guarantee the structure has. Deletion requires a variant like a counting Bloom filter, which trades more memory for that ability.

Discussion

Sign in to join the discussion · reading is open to everyone

💡 Discussion rules

  1. Ask and answer about this concept. Off-topic gets removed.
  2. No homework dumps. Show what you tried first.
  3. Corrections are welcome. Cite a source when you claim an error.

Loading discussion…

Related concepts

Practice in interviews

Further reading

  • Bloom, 'Space/Time Trade-offs in Hash Coding with Allowable Errors' (1970)
  • Broder & Mitzenmacher, 'Network Applications of Bloom Filters: A Survey'
ShareTwitterLinkedIn