LearnastraTHE DESIGN COURSE

Understand the building blocks / CHAPTER 23

Bloom filters

Use a small bit array to avoid expensive absent-key lookups while keeping exact records and decisions in the database.

Intermediate1h of deliberate study10 questions

Builds on Caching fundamentals, Database indexes.

By the end, you can
  • Explain bit-array insertion and membership testing.
  • Distinguish possible presence from definite absence under explicit assumptions.
  • Size the filter and protect against staleness, deletion, and rebuild races.

01Represent possible membership with shared bits

A storage service receives many requests for keys that do not exist. Before an expensive disk lookup, it can use a small bit array to rule out some definite misses. This structure is a Bloom filter; it does not store the full records.

Build a toy filter with twelve positions numbered 0 through 11:

  1. Start every bit at zero. A bit holds either zero or one.
  2. Run repeatable hash calculations on cat. Suppose they choose positions 2 and 7. Insert cat by setting those bits to one.
  3. Insert dog at its positions 7 and 10. The set positions are now 2, 7, and 10; bit 7 is shared.
  4. To test a key, calculate its positions using the same key bytes and hash settings.
  5. If any required bit is zero, that key was not successfully inserted into this filter.
  6. If every required bit is one, the key is only possibly present. Another key may have set those bits.

For example, fox chooses positions 2 and 10. Both are one although fox was never inserted. This is a false positive. owl chooses 1 and 9; the zero at 1 rules out its insertion into this filter.

An intact ordinary insert-only filter does not reject a successfully inserted key after insertion completes: all its required bits remain one. This no-false-negative property assumes unchanged hashes and key encoding, no damaged bits, and no unsafe deletion. It does not prove every current database record has already reached the filter.

02Use it as a gate, not an exact authority

Use the filter as a preliminary check, followed by an exact store when needed:

  1. A positive means “possibly present.” Ask the exact store for the record or final decision.
  2. A negative can avoid that lookup only if all relevant committed keys are already covered by the filter or another checked complete set.
  3. If coverage is uncertain, query the exact source instead of hiding a potentially real record.

Estimate the benefit separately from the guarantee:

  1. Assume 10,000 lookups for keys actually absent from the exact store.
  2. At a 1% false-positive rate, about 10000 × 0.01 = 100 still require exact lookups.
  3. About 9,900 avoid those expensive misses under complete coverage. Present keys also pass and still need the record when its contents or authoritative decision matters.

Size the filter for expected insertions. More bits per key generally reduce false positives; inserting too many keys into a fixed array raises them as more positions become one.

A standard approximate model uses:

  • m: the number of bits.
  • n: the number of inserted keys.
  • k: the number of hash positions per key.
  • False-positive probability: (1−e^(−kn/m))^k, where e is the natural exponential constant.
  • A useful hash count near (m/n) × ln(2), with ln(2) ≈ 0.693.

For one million keys and about 1% false positives, the model suggests roughly 9.6 million bits. Divide by eight for 1.2 million bytes, or 1.2 MB of bit-array storage, and use about seven hash positions. Extra structures add overhead. These estimates depend on the hash-distribution assumptions; they are not guarantees for arbitrary inputs.

03Keep coverage and deletion safe

A database saves a new document at 12:00:01, but the filter refreshes only once a minute. A 12:00:02 lookup may test negative because the new key was never inserted into that filter. Skipping the database now can hide a real document.

Protect coverage explicitly:

  1. The simplest fallback queries the exact database whenever coverage is uncertain.
  2. One concrete alternative saves the document and a recent-key row in the same database transaction. After a filter negative, check that small recent-key table with a read that can see completed inserts. A key found there requires the ordinary exact document lookup.
  3. Build a replacement filter from a database snapshot and record which committed inserts it includes. Switch readers to that build before removing the recent-key rows it includes. Keep those rows while any reader can still use an older filter, and keep newer rows until a later build includes them. If the service cannot establish which build readers use, do the full database lookup instead.
  4. If the recent-key check or rebuild coverage cannot be established, use the full database lookup. This alternative adds a recent-table lookup to negative requests; compare that cost with the expensive source probes it saves.

Deletion has a different hazard:

  1. Cat and dog both use bit 7 in the example.
  2. Clearing bit 7 to delete dog makes cat test negative even though cat was inserted.
  3. Ordinary shared bits therefore cannot be cleared safely for individual deletion.

Counting Bloom filters store counters instead of single bits. Deleting dog reduces its position counters while preserving counts contributed by cat. This requires correct insertion/deletion bookkeeping and overflow handling; deleting an uninserted key can also damage the counts. Rebuilding from the exact source is another option.

Separate consequences:

  • A deleted key that still tests positive usually costs an extra exact lookup, which returns absent.
  • A committed new key missing from the filter can cause a wrong absence if negatives bypass the source.
  • A positive never proves username uniqueness, permission, or a completed payment. Use the exact authoritative operation, including its concurrency rules.

Monitor insert count, observed false positives, and rebuild coverage. A good miss-saving estimate does not replace a complete view of which keys the filter represents.

Shared bits create a possible-presence false positive

Shared bits create a possible-presence false positiveInsert cat at positions 2 and 7. Insert dog at 7 and 10, sharing bit 7. Test fox at 2 and 10; both positions are already one. Treat the result as possibly present and consult the exact store. Numbered arrows correspond to the connection key below. All connections are directional.Insert catSets bits 2 and 7Insert dogSets bits 7 and 10Shared arraySet positions: 2, 7,10Test foxHashes to 2 and 10All tested bitssetPossibly presentExact storefox may still beabsent12345Shared bits create a possible-presence false positiveInsert cat at positions 2 and 7. Insert dog at 7 and 10, sharing bit 7. Test fox at 2 and 10; both positions are already one. Treat the result as possibly present and consult the exact store. Numbered arrows correspond to the connection key below. All connections are directional.Insert catSets bits 2 and 7Insert dogSets bits 7 and 10Shared arraySet positions: 2, 7,10Test foxHashes to 2 and 10All tested bitssetPossibly presentExact storefox may still beabsent12345Shared bits create a possible-presence false positiveInsert cat at positions 2 and 7. Insert dog at 7 and 10, sharing bit 7. Test fox at 2 and 10; both positions are already one. Treat the result as possibly present and consult the exact store. Numbered arrows correspond to the connection key below. All connections are directional.Insert catSets bits 2 and 7Insert dogSets bits 7 and 10Shared arraySet positions: 2, 7,10Test foxHashes to 2 and 10All tested bitssetPossibly presentExact storefox may still beabsent12345

Follow the numbered arrows

  1. Insert cat → Shared arrayset selected bits
  2. Insert dog → Shared arraybit 7 is shared
  3. Test fox → Shared arraytest same configured hashes
  4. Shared array → All tested bits setall-one result
  5. All tested bits set → Exact storeverify authoritative membership
Cat and dog set shared positions 2, 7, and 10. Fox tests 2 and 10 and passes despite never being inserted. The filter therefore sends fox to an exact lookup, which decides whether the record really exists.
Trace the diagram in words
  1. Insert cat at positions 2 and 7.
  2. Insert dog at 7 and 10, sharing bit 7.
  3. Test fox at 2 and 10; both positions are already one.
  4. Treat the result as possibly present and consult the exact store.

DRAW. CALCULATE. EXPLAIN.

Audit a minute-delayed document filter

20 minutes · guided practice

The database accepts 100 new documents per second. Its Bloom filter refreshes once per minute, and a filter negative skips the database lookup.

  1. Estimate how many recently committed identifiers can be missing near the end of the interval.
  2. Explain a safe immediate fallback.
  3. Explain what a recent-key set or rebuilt filter must guarantee.
Your self-check
Compare the worked solution
  1. Sixty seconds adds 100 × 60 = 6000 committed identifiers. Near the interval’s end, the old filter may omit roughly 6,000, before adding any rebuild duration.
  2. Query the exact database whenever the filter’s coverage is uncertain. Its negative cannot prove those new documents are absent.
  3. Alternatively, save the document and a recent-key row in one database transaction. A filter negative also checks that table using a read that sees completed inserts; a recent key proceeds to an exact document lookup. Remove its recent row only after the installed filter includes that committed key.
  4. A rebuild must include concurrent insertions before the switch. Positives still require the exact record lookup or the database’s atomic uniqueness decision.

The checkboxes record your own assessment. The worked solution gives you a way to check the reasoning.

RETRIEVE BEFORE YOU REVEAL

Keep the important ideas.

Say the answer aloud, then turn the card over.

CARD 01What does a Bloom result mean?
  1. Compute the key’s configured bit positions.
  2. Any zero means it was not successfully inserted into this filter.
  3. All ones mean only possibly present, because different keys share bits.
  4. Use the exact store for the record or final decision.
CARD 02When are there no false negatives?

No false negatives applies after completed insertion into an intact ordinary insert-only filter with the same bytes and hashes.

It does not cover missing database-to-filter updates, corruption, unsafe deletion, or changed input encoding.

CARD 03How do I integrate it safely?
  1. Skip the source on a negative only when coverage of relevant committed keys is established.
  2. Include live inserts during rebuilds, or check a coordinated recent-key set.
  3. Query the exact source when coverage is uncertain.
  4. Do not clear ordinary shared bits to delete one key.
Practise this topic in the revision deck ↗

CHECK THE REASONING

Can you explain the choice?

Answer every question, then finish for an immediate score and an explanation for each answer. Aim for 80%, then revisit any gaps.

1 / 10cat sets 2,7 and dog sets 7,10. fox hashes to 2,10. What does the filter say?
2 / 10owl hashes to 1,9 and bit 1 is zero. What does an intact insert-only filter establish?
3 / 10The database commits d9 before the minute-delayed filter update. What is unsafe?
4 / 10Deleting dog by clearing shared bit 7 can do what?
5 / 10At 1% false positives among 10,000 absent-key lookups, roughly how many reach the exact store?
6 / 10What does exceeding planned insertion capacity tend to do?
7 / 10A username filter returns positive. What must registration use?
8 / 10A rebuilt filter covers yesterday’s snapshot. What must happen before switching live negative checks?
9 / 10A deleted source key remains positive in a filter whose positives are verified exactly. What is the usual immediate effect?
10 / 10Why must insertion and lookup use the same canonical encoding?
0 of 10 answered

CLOSE THE LOOP

Explain it without the page.

Summarise the mechanism, one trade-off, and one failure mode. Then mark this chapter complete.

Go to the source