Answering Have We Seen This Before?
Imagine a receptionist with a very long guest list and a tiny desk card. The card can quickly say “definitely not on the list” or “possibly on the list; check the register.” It cannot reliably name every guest. A membership filter plays that role for a large set of keys. Its useful trade is a small amount of memory for occasional false positives: an absent key may appear present. Under the right update rules, an inserted key will never appear absent.
Take an eight-position bit card, initially all zero. Suppose inserting A marks positions 1 and 4, and inserting B marks 4 and 6. The marked positions are now 1, 4, and 6. An absent C whose two positions are 1 and 6 looks present: a false positive. An absent D whose positions are 1 and 2 is definitely absent because position 2 is zero. This example depends on the positions supplied by the hash functions; a real guarantee averages over their specified random choice for a fixed collection of keys.
Why does this matter? A cache may use the card to avoid a fruitless disk lookup, a security service may narrow candidates for an authoritative blocklist, and an event pipeline may screen potential duplicates before checking a durable ID store. The last check is crucial: treating “possibly seen” as proof of a duplicate can discard a new event. We will distinguish the set represented by the filter, the keys seen in a stream, and the records actually committed by a system.
A standard Bloom filter answers “definitely absent” or “possibly present” for an insert-only set. Its one-sided error applies only while the hash functions, stored bits, and update assumptions remain valid; “possibly present” is not proof that a key was inserted.
| Term | Intuitive meaning and exact example | Boundary or non-example | Question answered |
|---|---|---|---|
| Represented set | Keys actually inserted, such as $S=\{A,B\}$ | An event merely received upstream may not be inserted yet | What truth are queries compared against? |
| False positive | Absent C checks set positions 1 and 6 | A positive is not evidence of C's insertion | How can “possibly present” be wrong? |
| False negative | Inserted B receives “absent” | Excluded by a valid insert-only Bloom filter; possible after unsafe deletion | Could the filter miss a member? |
| Fingerprint | Short digest stored in a slot, such as a 10-bit value | Digest equality does not prove full-key equality | What compressed identity is compared? |
| Occupancy | Fraction of Bloom bits set, or slots filled in a table | These are different measures in different filters | How close are we to capacity? |
| Duplicate screen | A positive triggers an exact ID lookup | Dropping solely on a positive loses fresh events | Which work can be avoided safely? |
Answering Have We Seen This Before?
Draw eight boxes labeled 0–7. Insert A at positions $(1,4)$ and B at $(4,6)$, marking 1, 4, 6. Query C at $(1,6)$ and D at $(1,2)$. Checkpoints: C gets “possibly present” despite being absent; D gets “absent” because bit 2 is zero. Query B at $(4,6)$ and verify it stays positive. Expected result: one false positive, no false negative in this trace. Reflection: what would happen to B if you attempted to delete A by clearing both of A's bits?
Bits, Fingerprints and One-Sided Error
Fix a universe $U$ and represented set $S\subseteq U$ with $n$ distinct keys. A membership query answers whether $x\in S$. For a conventional Bloom filter, keep $m$ bits and use $k$ hash positions per key. Insertion sets all $k$ positions to one; a query is negative if any of those positions is zero, otherwise positive. Bits never return to zero in the basic insert-only design. Therefore every key successfully inserted remains positive deterministically, even when positions collide. For a fixed absent query, a stated false-positive probability is over the random choice of hashes under a specified input and query model. It does not say that every absent key is unlikely to be positive simultaneously.
Deletion changes the contract. A counting Bloom filter replaces bits with small counters, increments the positions on insertion, and decrements them only for a key whose insertion is known and whose multiplicity is tracked appropriately. A membership query checks whether all relevant counters are positive. Counter overflow, a missing update, or deleting an absent key based on a false positive can produce false negatives. A simple Bloom filter cannot safely delete by clearing bits shared with other keys.
Fingerprint-based alternatives store compressed tags rather than the entire key. A cuckoo filter stores a fingerprint in one of two candidate buckets and may move existing fingerprints during insertion; a failed displacement at high load needs an explicit retry, growth, or rejection policy. An XOR filter generally builds an array for a fixed key set so the XOR of a query's addressed cells agrees with its fingerprint on members. Construction may need a new seed or larger table if peeling fails; ordinary incremental insertion or deletion is not part of that static contract. A quotient filter stores a hash's quotient and remainder with metadata that allows runs of related fingerprints to be found; capacity, clustering, and the chosen variant govern update costs and deletion. Fingerprint matches can be false positives, so the precise rates depend on construction and load, not just a label such as “10-bit fingerprint.”
flowchart TD
S["Committed set S"] --> U{"Update model"}
U -->|Insert only| B["Bloom: set k bits"]
U -->|Known insert and delete| C["Counting or dynamic variant"]
U -->|Static batch| X["Build XOR filter"]
B --> Q["Query all k positions"]
C --> Q
X --> F["Compare fingerprint"]
Q --> N["Any zero: absent"]
Q --> P["All positive: possibly present"]
F --> P
classDef navy fill:#17365D,color:#fff,stroke:#17365D;
classDef teal fill:#147D84,color:#fff,stroke:#147D84;
classDef crimson fill:#C6284D,color:#fff,stroke:#C6284D;
classDef purple fill:#6C3BAA,color:#fff,stroke:#6C3BAA;
class S,U navy; class B,C,X teal; class Q,F purple; class N,P crimson;
| Structure | Stored state and supported operation | Error and assumption | Failure boundary |
|---|---|---|---|
| Basic Bloom | $m$ bits; insert and query | No false negatives after completed insertions; absent keys may be positive | Clearing a shared bit can hide a member |
| Counting Bloom | Counters at hashed positions; insert, known-key delete, query | No false negatives if multiplicities, overflow, and updates are handled | Deleting a false positive can decrement someone else's counters |
| Cuckoo filter | Fingerprints in candidate buckets; insert, query, qualified delete | Fingerprint collision can yield positive for absent key | Relocation can fail at high occupancy |
| Quotient filter | Quotients, remainders, and run metadata; dynamic operations vary by variant | Fingerprint collisions cause false positives | Clustering and capacity affect time and success |
| XOR filter | Array satisfying fingerprint equations for a built set | Fast static query; members pass after successful build | Build can fail and must retry; new keys require rebuild or a layered design |
| Exact set | Full key identities; exact membership | No probabilistic error if maintained correctly | Higher memory and lookup costs |
The one-sided guarantee is conditional on a correctly maintained represented set: an inserted member's Bloom positions stay set, so it cannot receive “absent.” A false positive concerns a fixed nonmember under the specified hash-randomness model; inconsistent replicas, unsafe deletion, and stale updates are outside that idealized claim.
Deriving False Positives and Capacity Limits
Assume $k$ independent uniform positions for each of $n$ distinct inserted keys in an $m$-bit array, chosen with replacement. A particular bit avoids one position with probability $1-1/m$, so its probability of remaining zero after $kn$ position choices is exactly $(1-1/m)^{kn}$ under this ideal model. Thus its expected occupancy fraction is $q=1-(1-1/m)^{kn}\approx1-e^{-kn/m}$. The familiar false-positive design formula $p_{\mathrm{FP}}\approx(1-e^{-kn/m})^k$ additionally treats the tested positions and occupancy as if they were suitably independent and concentrated. For finite $m$, this is an approximation, not an exact consequence of the one-bit expectation: the bit states are correlated. Measure or bound actual rates when these approximations or the hash construction matter.
Minimizing that approximate expression with $m$ and $n$ fixed gives $k_{\mathrm{opt}}\approx(m/n)\ln2$. At this point roughly half the bits are set. Solving for a desired approximate false-positive target $p$ gives $m\approx-n\ln p/(\ln2)^2$ bits. For $n=1{,}000$ and $p=0.01$, this is about $9{,}585$ bits, roughly $1{,}199$ bytes, and $k\approx6.64$, so evaluate the nearby integers $6$ and $7$. These figures omit metadata, alignment, hash seeds, and any operational headroom. If actual unique keys exceed $n$, occupancy and false positives rise; repeated insertion of the same key does not create $k$ fresh independent positions in a deterministic Bloom filter.
For the eight-bit warm-up, after A and B the occupied set is $\{1,4,6\}$. It is tempting to subtract A by clearing 1 and 4, but B also needs 4, so querying B then finds a zero and gives a false negative. Counting bits instead yields counts at positions 1, 4, 6 of $1,2,1$ if the two positions per key are distinct. Decrementing A correctly leaves $0,1,1$, preserving B. A mistaken deletion of C, whose positions 1 and 6 only look present, would decrement counters belonging to A and B and can damage the invariant.
A filter's headline rate is often the probability for one fixed absent query, not the probability that a whole query workload has no false positives. If a workload contains $Q$ fixed absent queries each with false-positive probability at most $p$, the union bound gives probability at most $Qp$ of at least one false positive, capped at 1; it needs no independence. An attacker who adaptively probes a public filter and then selects a known positive is not covered by that fixed-query statement. For high-consequence decisions, the positive branch must be verified against authoritative state.
flowchart TD
A["m bits; k positions; n distinct keys"] --> Z["One bit stays zero with (1−1/m)^(kn)"]
Z --> O["Expected occupied fraction q"]
O --> P["Approximate nonmember rate q^k"]
P --> K["Choose k near (m/n) ln 2"]
K --> M["Budget m for target rate and headroom"]
O --> D{"Need deletions?"}
D -->|Yes| C["Count positions; verify actual membership"]
D -->|No| B["Keep monotone bits"]
C --> F["Overflow or wrong deletion breaks guarantee"]
classDef navy fill:#17365D,color:#fff,stroke:#17365D;
classDef teal fill:#147D84,color:#fff,stroke:#147D84;
classDef crimson fill:#C6284D,color:#fff,stroke:#C6284D;
classDef purple fill:#6C3BAA,color:#fff,stroke:#6C3BAA;
class A,Z navy; class O,P,K,M,B teal; class F crimson; class D,C purple;
Deriving False Positives and Capacity Limits
Given: $n=1{,}000$ distinct inserts, target approximate rate $p=0.01$, and idealized uniform hashing. Compute $m\approx-1{,}000\ln(0.01)/(\ln2)^2\approx9{,}585$ bits. Then $k_{\mathrm{opt}}\approx(9{,}585/1{,}000)\ln2\approx6.64$; test $k=7$ and estimate occupancy $1-e^{-7{,}000/9{,}585}\approx0.518$, so estimated false-positive rate is about $0.518^7\approx0.0100$. Checkpoint: the estimate is a design approximation, not a deterministic guarantee for one built filter. Variation: with $2{,}000$ distinct inserts and the same $m,k$, approximate occupancy becomes $1-e^{-14{,}000/9{,}585}\approx0.768$, giving false-positive rate about $0.768^7\approx0.158$. Conclusion: an unplanned doubling of unique keys can radically change the service's error budget.
| Reasoning step | Establishes | Assumption or precision | Failure case |
|---|---|---|---|
| Zero-bit calculation | $\Pr(\text{one bit zero})=(1-1/m)^{kn}$ | Independent uniform position choices in the ideal model | Weak correlated hash outputs alter occupancy |
| Occupancy heuristic | $p_{\mathrm{FP}}\approx(1-e^{-kn/m})^k$ | Approximation for absent fixed query; dependencies ignored | Treating it as an exact finite-size identity |
| Optimal parameter heuristic | $k\approx(m/n)\ln2$ | Fixed target $n,m$ under approximate model | Real key count greatly exceeds design count |
| Monotonicity invariant | Successfully inserted key's Bloom bits remain one | No bit clearing or incomplete replication | Unsafe deletion yields a false negative |
| Counting deletion | Shared counters preserve other keys | Known inserted key, correct multiplicity, no overflow | Decrement after a false positive |
| Workload union bound | At most $Qp$ chance of any positive among $Q$ fixed absent queries | Individual fixed-query bound for each | Adversary picks query after probing outputs |
Cache Admission, Abuse Lists and Deduplication
Approachable cache. A cache keeps an exact database of stored objects behind a Bloom filter. When a requested key tests negative, the cache can skip a pointless database lookup if the filter is complete and current. A positive goes to the database: it may be an actual hit or a false positive that costs one extra lookup. This arrangement preserves correctness while reducing work. During asynchronous insertion, “complete and current” must be defined: if the database contains a key before the filter receives its update, a negative can wrongly bypass that record.
Production event deduplication. Suppose a pipeline ingests $50$ million events per day, expects $5$ million unique event IDs in a rolling epoch, and can budget roughly $1$ MiB of filter bits per million IDs at a chosen false-positive rate. The durable ID store remains authoritative. A negative can proceed to an exact insert path, while a positive triggers a lookup or an atomic insert-if-absent; neither branch should drop an event merely because of the filter. The actual protocol must handle races, retries, crashes, and epoch rotation. Bloom bits cannot remove old keys safely; rotate whole epoch filters or choose a deletion-capable design with correct multiplicities. Measure unique IDs, occupancy, extra lookups, update lag, and false negatives caused by system inconsistency separately from theoretical hash false positives.
Abuse list and malicious probing. A service screens incoming account IDs against a blocklist. A false positive must not by itself deny service, because an innocent ID may collide; positives should be checked against an authoritative list. If an attacker can probe the public filter and choose IDs that test positive, the fixed-query false-positive rate does not limit the attacker-selected workload. If a list changes, stale replicas can also produce negatives for recently blocked IDs or positives for removed ones. State freshness, authorization and threat assumptions before using “no false negatives” as an operational promise.
Cache Admission, Abuse Lists and Deduplication: Membership Filters & Duplicate Detection
Inputs: authoritative set $S=\{A,B\}$; eight filter positions; A maps to $(1,4)$, B to $(4,6)$, absent C to $(1,6)$, absent D to $(1,2)$. Model selection: use an insert-only Bloom precheck before exact membership. Trace: C is positive but the exact set says absent; D is negative and can bypass the lookup; A and B are positive and confirmed present. Success criterion: classify all four outputs and count exactly one unnecessary lookup, assuming one query per key and a complete filter. Changed assumption: delete A by clearing positions 1 and 4; show B now receives a false negative, then explain why a confirmed-key counting deletion would preserve B.
Cache Admission, Abuse Lists and Deduplication: Membership Filters & Duplicate Detection
Scenario: $50$ million events/day, about $5$ million unique IDs per epoch, concurrent writers, repeat deliveries, and a false-positive goal of $0.01$. Budget: the Bloom approximation calls for about $5{,}000{,}000\times9.585\approx47.9$ million bits, about $5.7$ MiB of bits before metadata and operational headroom; about seven hash positions per key. Contract: an authoritative atomic insert-if-absent determines duplicate status. A filter positive may add a lookup, never drop an event; a negative takes the insert path, with synchronization rules keeping the filter complete for the represented set. Evidence: track unique counts and occupancy by epoch, measured absent-query positives, lag and lost updates, race outcomes, retries, and rebuild time. Decision: rotate complete filters for expiring epochs or choose a deletion-capable alternative only with a validated delete and overflow policy. Acceptance requires a written failure action for unavailable exact storage and a clear difference between hash error and operational inconsistency.
Select a Filter Under Real Constraints
Choose a filter by the permissible mistake, population size, mutation pattern, and action taken after a positive result. The same approximate membership answer can be safe as a lookup precheck and unsafe as a final security or financial decision. These exercises make each premise and failure path explicit.
Practice: Select a Filter Under Real Constraints
Level 1 — Define (2 points). With inserted A and B and absent C that hashes onto set bits, name the error. Expected: C is a false positive; A and B are not false positives because they are members. State why “possibly present” needs confirmation for deduplication.
Level 2 — Derive (2 points). For $m=1{,}000$, $n=100$, $k=7$, estimate bit occupancy as $1-e^{-0.7}\approx0.503$ and false-positive rate as $0.503^7\approx0.0082$. Hint: label this a design approximation. Expected artifact: equations, units, and one sentence on bit-state dependence.
Level 3 — Counterexample (2 points). Use A at $(1,4)$ and B at $(4,6)$. Show that clearing A's two bits makes B negative. Expected: shared bit 4 is the broken invariant. Give safe counting-filter counts before and after deleting known-present A, and explain why deleting absent C based only on a positive query is unsafe.
Level 4 — Compare (2 points). Choose a structure for a static nightly blocklist, a mutable set with known-key deletions, and a cache precheck. Expected: consider a successfully built XOR filter for the static snapshot, a validated dynamic/counting or cuckoo design for deletions, and an insert-only Bloom precheck for the cache. List one failure mode and an exact verification path for each.
Level 5 — Professional decision (2 points). Design a deduplication screen for $5$ million unique IDs per epoch and approximate target $0.01$. Artifacts: bit and hash budget, actual distinct-count headroom, authoritative lookup/atomic insert flow, synchronization and epoch-rotation protocol, and an adversarial-query test. Rubric: model and error target 2, parameter derivation 2, deletion/expiration 2, exact-action safety 2, monitoring and adversary 2. Stretch: compare memory, build failure, and deletion policies of quotient, cuckoo, and XOR options using measured implementation results rather than assuming their names confer identical guarantees.
Record the represented set, expected distinct-key count, one-query and workload error budgets, hash assumptions, update and deletion rules, and the exact action following “possibly present.” A filter complements authoritative state; the next distinct-element and frequency-estimation topics use related hashing ideas to answer different questions that membership alone cannot solve.
Next in the Series
In Distinct Elements & Set Cardinality, we'll explore Estimate F0 from hash-order statistics and register patterns..