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.
Builds on Caching fundamentals, Database indexes.
- 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:
- Start every bit at zero. A bit holds either zero or one.
- Run repeatable hash calculations on
cat. Suppose they choose positions 2 and 7. Insertcatby setting those bits to one. - Insert
dogat its positions 7 and 10. The set positions are now 2, 7, and 10; bit 7 is shared. - To test a key, calculate its positions using the same key bytes and hash settings.
- If any required bit is zero, that key was not successfully inserted into this filter.
- 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:
- A positive means “possibly present.” Ask the exact store for the record or final decision.
- A negative can avoid that lookup only if all relevant committed keys are already covered by the filter or another checked complete set.
- If coverage is uncertain, query the exact source instead of hiding a potentially real record.
Estimate the benefit separately from the guarantee:
- Assume 10,000 lookups for keys actually absent from the exact store.
- At a 1% false-positive rate, about
10000 × 0.01 = 100still require exact lookups. - 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, whereeis the natural exponential constant. - A useful hash count near
(m/n) × ln(2), withln(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:
- The simplest fallback queries the exact database whenever coverage is uncertain.
- 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.
- 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.
- 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:
- Cat and
dogboth use bit 7 in the example. - Clearing bit 7 to delete
dogmakescattest negative even thoughcatwas inserted. - 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
Follow the numbered arrows
- Insert cat → Shared arrayset selected bits
- Insert dog → Shared arraybit 7 is shared
- Test fox → Shared arraytest same configured hashes
- Shared array → All tested bits setall-one result
- All tested bits set → Exact storeverify authoritative membership
Trace the diagram in words
- Insert 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.
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.
- Estimate how many recently committed identifiers can be missing near the end of the interval.
- Explain a safe immediate fallback.
- Explain what a recent-key set or rebuilt filter must guarantee.
Compare the worked solution
- Sixty seconds adds
100 × 60 = 6000committed identifiers. Near the interval’s end, the old filter may omit roughly 6,000, before adding any rebuild duration. - Query the exact database whenever the filter’s coverage is uncertain. Its negative cannot prove those new documents are absent.
- 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.
- 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?
- Compute the key’s configured bit positions.
- Any zero means it was not successfully inserted into this filter.
- All ones mean only possibly present, because different keys share bits.
- 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?
- Skip the source on a negative only when coverage of relevant committed keys is established.
- Include live inserts during rebuilds, or check a coordinated recent-key set.
- Query the exact source when coverage is uncertain.
- Do not clear ordinary shared bits to delete one key.
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.
CLOSE THE LOOP
Explain it without the page.
Summarise the mechanism, one trade-off, and one failure mode. Then mark this chapter complete.