Overview

3 Approximate Membership: Bloom filter and Quotient filter

This chapter introduces approximate membership data structures for massive data processing, centering on Bloom filters and quotient filters. It explains why these compact structures are so widely used in networks, storage systems, and streaming pipelines: they provide fast insert and lookup with small memory footprints at the cost of controlled, one-sided errors. The text balances practice and theory—showing how to implement and tune parameters, deriving key formulas and lower bounds, and surveying real deployments—before contrasting Bloom and quotient filters to clarify when each is a better fit.

The Bloom filter portion covers mechanics (a bit array plus k hash functions), operations (O(k) insert/lookup), and error behavior (false positives but no false negatives), highlighting scenarios where most queries are absences. It illustrates production use in systems such as SST-based stores, web proxies, and light cryptocurrency clients, and provides a simple Python implementation. A configurable framework relates space, dataset size, number of hashes, and false-positive rate, with practical guidance like choosing k ≈ (m/n)·ln 2 and noting that unsuccessful lookups typically terminate after one or two probes. The chapter derives the standard error formula, argues via concentration bounds that it is tight in practice, and compares Bloom filters to theoretical lower bounds, showing they are close to optimal. It also surveys adaptations (e.g., counting, weighted, and adaptive variants) and candidly discusses limitations such as deletions and resizing.

The quotient filter section presents a compact, linear-probing hash-table design that stores fingerprints via quotienting (splitting into bucket index and remainder) and uses three metadata bits to maintain runs and clusters. This enables efficient deletion, resizing, and fast linear-time merging—capabilities that make quotient filters attractive in dynamic, distributed settings—at the expense of extra CPU work for decoding and tighter sensitivity to load factor. The chapter analyzes space/error trade-offs (fingerprint length versus false positives), notes that quotient filters are usually slightly larger than Bloom filters at common error targets but can be better at extremely low rates, and summarizes empirical comparisons: quotient filters tend to have faster inserts and successful lookups until high occupancy, while Bloom filters excel at uniform negative lookups and show steadier performance. The guidance closes with workload-driven recommendations based on throughput, CPU locality, deletion and resizing needs, and storage medium characteristics.

: Bloom filters in distributed storage systems. In this example, we have 50 Sorted String Tables (SSTs) on disk, and each table has a dedicated Bloom filter that can fit into RAM due to its much smaller size. When a user does a lookup, the lookup first checks the Bloom filters, thus avoiding expensive disk seeks.
: Example of insert into Bloom filter. In this example, an initially empty Bloom filter has m=8, and k=2 (two hash functions). To insert an element x, we first compute the two hashes on x, the first one of which generates 1 and the second one generates 5. We proceed to set A[1] and A[5] to 1. To insert y, we also compute the hashes and similarly, set positions A[4] and A[6] to 1.
03_02
: Example of a lookup on a Bloom filter. To do a lookup on x, we compute the hashes (which are the same as in the case of an insert), and we return Found/Present, as both bits in corresponding locations equal 1. Then we do a lookup of an element z, which we never inserted, and its hashes are respectively 4 and 5, and bits at locations A[4] and A[5] equal 1, thus we again return Found/Present.
: Usage of Bloom filter in Squid web proxy. A user requests a web page x, and a web proxy A can not find it in its own cache, so it locally queries the Bloom filters of B, C and D. The Bloom filter for D reports Present, so the request is forwarded to D. The resource is found at D and returned to the user.
: In Bitcoin, light clients can broadcast what transactions they are interested in, and thereby block the deluge of updates from the network.
: The plot relating the number of hash functions (k) and the false positive rate (f) in a Bloom filter. The graph shows the false positive rate for a fixed bits-per-element ratio (m/n), different curves corresponding to different ratios.
03_06_F4
: The inequality describing the space-error lower bound.
: Quotienting in a hash table. The item y has the hash 10100 101101, therefore the remainder 101101 (35) will be stored in the slot determined by quotient, at bucket 10100 (20).
: Insertion into quotient filter and metadata bits.
: Insertion of y and z into the quotient filter.
:11: The memory layout of quotient filter slots.
: Resizing a quotient filter of size 4 that contains 3 elements. For the sake of simplicity, we assume that no collisions occurred between those 3 elements and ever remainder is stored in its original bucket. A fingerprint 110010 that hashed to bucket 11 (with remainder 0010) in the original quotient filter gets stored at 110 bucket of the second quotient filter (with remainder 0010), and in a 1100 bucket of the final quotient filter (with remainder 010.)
: Performance comparison of Bloom filters and quotient filters on inserts, uniform random lookups, and successful lookups, respectively.

 Summary

  • Bloom filters have been widely applied in the context of distributed databases, networks, bioinformatics, and other domains where regular hash tables are too space-consuming.
  • Bloom filters trade accuracy for the savings in space, and there is a relationship between the space, false positive rate, the number of elements and the number of hash functions in the Bloom filter.
  • Bloom filters do not meet the space vs. accuracy lower bound, but they are simpler to implement than more space-efficient alternatives, and have been adapted over time to deal with deletes, different query distributions, etc.
  • Quotient filters are based on compact hash tables with linear probing and are functionally equivalent to Bloom filters, with the benefit of spatial locality, ability to delete, merge and resize efficiently.
  • Quotient filters are based upon the space-saving method of quotienting and extra metadata bits that allow the full fingerprint reconstruction.
  • Quotient filters offer better performance than Bloom filters on uniform random inserts and successful lookups, while Bloom filters win over on uniform random (unsuccessful) lookups. The performance of quotient filters is dependent on a load factor (lower load factor is better), and the performance of Bloom filters is dependent on the number of hash functions (fewer hash functions is better).

FAQ

What problem do Bloom filters solve, and when should I use them?Bloom filters answer approximate membership queries using very little space (often under 1 byte per item). They are ideal when most queries are expected to be negative, and expensive storage lookups (SSD/disk or network) must be avoided. Typical use cases include routing lookups to the right on-disk table in distributed stores (e.g., SSTables), network cache summaries (e.g., Squid), and filtering updates for light clients (e.g., Bitcoin SPV).
How do Bloom filters work and what errors do they make?A Bloom filter maintains a bit array and k independent hash functions. Insert sets k bits; lookup checks those k bits. It never has false negatives (if it says Not Present, it’s correct), but it may have false positives (it may say Present for an item never inserted). This one-sided error is useful when negative answers dominate and avoiding slow I/O is critical.
How should I configure a Bloom filter (m, n, k, f)?Given n (items) and target false-positive rate f, set: - m ≈ −n ln(f) / (ln 2)² bits - k ≈ (m/n) ln 2 At the k that minimizes f, the false-positive rate satisfies f ≈ (1/2)^k and the fraction of 1-bits is about 50%. Typical bits-per-element (m/n) between 6 and 14 yield low single-digit percent false-positive rates with k around 4–8.
What happens if I insert more elements than planned?Over-inserting increases the fraction of 1-bits and drives up the false-positive rate sharply. If the actual n exceeds the design n (e.g., by 10×), performance can degrade dramatically. Track load and rebuild the filter (with a larger m or adjusted k) before it saturates; Bloom filters don’t gracefully “resize” in place.
How fast are Bloom filter operations?Insert and successful lookup touch k random bits (k is small, often 4–8). Unsuccessful lookups are very fast: in a well-configured filter they usually stop after checking only 1–2 bits on average. Overall, operations are O(k) and typically constant-time in practice.
What are common limitations and variants of Bloom filters?Limitations: - No native deletions and poor in-place resizing - Sensitive to skewed (Zipfian) query patterns for hot keys Variants: - Counting Bloom filter: supports delete using small counters (more space, can introduce false negatives via counter underflow) - Weighted/adaptive Bloom filters: devote more hashes to hot items or adapt after observed false positives These trade space/CPU for functionality.
What is a quotient filter and how does it differ from a Bloom filter?A quotient filter (QF) is a compact hash table that stores fingerprints (hashes) using linear probing. It splits each fingerprint into a quotient (bucket index) and remainder (stored). QFs can delete, resize, and merge efficiently, and they exhibit strong spatial locality (sequential scans). False positives arise only when two keys share the same fingerprint. Compared to Bloom filters, QFs are more CPU-intensive but offer richer dynamics (delete/resize/merge).
How does quotienting work, and what are the three metadata bits?Given a fingerprint, the high q bits form the quotient (bucket), and the low r bits form the remainder stored in that bucket’s run. To decode clusters after linear probing, each slot stores: - bucket_occupied: some key hashed to this bucket - run_continued: this slot continues the current run - is_shifted: this remainder was shifted from its original bucket These bits let the QF reconstruct runs/clusters and recover full fingerprints.
Can quotient filters be resized, merged, and support deletions?Yes. QFs can: - Delete: locate the remainder and adjust nearby slots (or use tombstones) - Resize: traverse in sorted fingerprint order, “steal” a bit from remainder to grow the quotient, and append into a larger table - Merge: linear-time merge two QFs like merging sorted lists Bloom filters, by contrast, generally require reloading the original keys to rebuild when resizing or merging.
How do Bloom and quotient filters compare in performance and space?Performance: - Inserts: QF often faster (fewer random writes), but slows at high occupancy (>~90%) due to larger clusters - Uniform random lookups: Bloom typically faster (1–2 bit checks on average for negatives) - Successful lookups: QF often competitive/faster until high load; Bloom stable (k probes) Space: - For common false-positive rates, Bloom filters tend to be slightly more space-efficient - For extremely low false-positive rates, QFs can be more space-efficient Other: - Bloom is simpler/CPU-light; QF offers deletes, resizing, merging, and better locality.

pro $24.99 per month

  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose one free eBook per month to keep
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime

lite $19.99 per month

  • access to all Manning books, including MEAPs!

team

5, 10 or 20 seats+ for your team - learn more


choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • Algorithms and Data Structures for Massive Datasets ebook for free
choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • Algorithms and Data Structures for Massive Datasets ebook for free
choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • Algorithms and Data Structures for Massive Datasets ebook for free