โ† Wiki Index / Computation & Algorithms / Cuckoo Filter
๐Ÿ’ป Computation & Algorithms

Cuckoo Filter

A cuckoo filter is a dynamic probabilistic set-membership data structure introduced by Bin Fan, Dave G. Andersen, Michael Kaminsky, and Michael D. Mitzenmacher in 2014 that uses partial-key cuckoo hashing over 4-slot buckets to support worst-case O(1) lookups and deletions at 95% table occupancy.

Cuckoo Filter is a compact, dynamic probabilistic data structure in computation and algorithms that tests approximate set membership with zero false negatives, worst-case O(1) lookup and deletion latency, and lower space overhead than a standard Bloom filter for false-positive rates ฮต < 3%. Introduced by Bin Fan, Dave G. Andersen, Michael Kaminsky, and Michael D. Mitzenmacher at ACM CoNEXT 2014, a cuckoo filter stores short f-bit fingerprints of inserted keys inside a bucketized cuckoo hashing table rather than setting bits in a flat bit array.

In computational complexity theory and high-throughput networking systems, classical Bloom filters prohibit element deletion (because clearing any bit B[hi(x)] could create false negatives for other stored keys sharing that bit) and require k = โŒˆ0.693 (m/n)โŒ‰ independent memory accesses per lookup. Counting Bloom filters support deletions only by inflating every bit into a 3- or 4-bit counter (3ร— to 4ร— memory overhead). By introducing partial-key cuckoo hashingโ€”an involutory bitwise XOR relocation scheme that computes a fingerprint's alternate bucket address without retaining the original keyโ€”a cuckoo filter with 4-slot buckets achieves 95.5% table occupancy, executes every lookup and deletion in at most two CPU cache-line reads, and supports Semi-Sorting bucket compression that saves an additional 1 bit per item.

Partial-Key Cuckoo Hashing and Bucketized Table Architecture

Why Standard Cuckoo Eviction Fails Without Full Keys

In standard cuckoo hashing (Pagh & Rodler, 2001), each key x is assigned two independent bucket locations i1 = h1(x) and i2 = h2(x) in an array of m buckets. When inserting a new key x into a full bucket i1, the table evicts an existing occupant y from bucket i1 and relocates y to its alternate bucket by recomputing h1(y) and h2(y) from the stored full key y.

In a compact approximate-membership filter, however, the full key y is discarded upon insertion; each slot stores only a short f-bit fingerprint ฯ„ = fingerprint(y) โˆˆ {1, ..., 2f โˆ’ 1} (typically f = 8, 12, or 16 bits, reserving the all-zero value 0 for empty slots). Because the original key y is no longer available during an eviction, evaluating an independent hash function h2(y) is impossible.

The Involutory XOR Identity of Partial-Key Cuckoo Hashing

Fan, Andersen, Kaminsky, and Mitzenmacher solved this relocation problem by defining the second candidate bucket index i2 as the bitwise exclusive-OR (โŠ•) of the first bucket index i1 and the hash of the f-bit fingerprint ฯ„ = fingerprint(x), where the number of buckets m = 2q is a power of two:

i1 = h1(x) mod m
i2 = i1 โŠ• h2(ฯ„) mod m

Because bitwise XOR is self-inverse (a โŠ• b โŠ• b = a), the relationship between i1 and i2 is fully symmetric:

i1 = i2 โŠ• h2(ฯ„) mod m

Consequently, whenever an incumbent fingerprint ฯ„ sitting in any current bucket i โˆˆ {i1, i2} is evicted during an insertion, its twin candidate bucket j is computed directly from i and ฯ„ aloneโ€”without knowing the original key x or even whether i was originally i1 or i2:

j = i โŠ• h2(ฯ„) mod m

Notably, hashing the fingerprint via h2(ฯ„) (rather than XORing the raw f-bit integer ฯ„ directly into i1) is essential: if ฯ„ were XORed without hashing when 2f โ‰ช m, the alternate bucket i2 would always lie within ยฑ2f slots of i1, causing pronounced localized clustering and premature insertion failure. Applying an invertible mixing hash h2(ฯ„) distributes alternate buckets across the entire m-bucket table.

Core Operations: Insertion, Lookup, and Safe Deletion

Bucketized (d = 2, b = 4) Layout and Lookup

A canonical cuckoo filter consists of an array T[0 .. m โˆ’ 1] of m buckets, where each bucket holds b = 4 fingerprint slots of f bits each. To test whether a query key x is in the set (Lookup(x)):

  1. Compute the f-bit non-zero fingerprint ฯ„ = fingerprint(x), the primary bucket i1 = h1(x), and the alternate bucket i2 = i1 โŠ• h2(ฯ„).
  2. Read the 4 slots of bucket T[i1] and the 4 slots of bucket T[i2] (which can be compared against ฯ„ in a single SIMD instruction). If any of the 2b = 8 slots contains ฯ„, return true; otherwise return false.

Eviction Insertion and Safe Deletion

  • Insertion (Insert(x)): Compute ฯ„, i1, and i2. If either bucket T[i1] or T[i2] has a vacant slot, store ฯ„ in that slot and return. Otherwise, pick i โˆˆ {i1, i2} at random and enter the cuckoo eviction loop (for up to MaxNumKicks = 500 iterations): randomly select one of the b = 4 fingerprints ฯ„โ€ฒ in T[i], swap ฯ„ โ†” ฯ„โ€ฒ, update i โ† i โŠ• h2(ฯ„), and return as soon as T[i] has a free slot.
  • Deletion (Delete(x)): Compute ฯ„, i1, and i2. If either bucket T[i1] or T[i2] contains a matching copy of ฯ„, clear one matching copy to 0 and return true. (As in any deletion-capable filter, only keys known to have been previously inserted may be deleted so as not to remove another member key that collided on both bucket and fingerprint; if identical keys are inserted multiple times, up to 2b = 8 duplicate copies can be stored across the two buckets.)

False-Positive Rate, Load Factor, and Space-Optimality Analysis

Fingerprint Length f as a Function of False-Positive Rate ฮต and Bucket Size b

When querying a non-member key y โˆ‰ S, the query inspects 2b slots across the two candidate buckets T[i1] and T[i2]. A false positive occurs if any of the occupied slots in those two buckets holds the same f-bit fingerprint ฯ„ = fingerprint(y). Because each stored fingerprint matches ฯ„ independently with probability 1 / 2f, the probability of a false positive across at most 2b comparisons is bounded by:

ฮต = 1 โˆ’ (1 โˆ’ 1 / 2f)2b โ‰ˆ 2b / 2f

Solving for the required fingerprint bit width f yields:

f โ‰ฅ โŒˆ log2(1 / ฮต) + log2(2b) โŒ‰ = โŒˆ log2(1 / ฮต) + 1 + log2 b โŒ‰ bits

Dividing by the maximum load factor ฮฑ of a (d = 2, b)-slot cuckoo table gives the amortized space cost C in bits per stored item:

C = f / ฮฑ = ( log2(1 / ฮต) + 1 + log2 b ) / ฮฑ bits per item
Bucket Capacity b (Slots/Bucket)Maximum Load Factor ฮฑExtra Bits per Fingerprint (1 + log2 b)Bits per Item C at ฮต = 1%Bits per Item C at ฮต = 0.1%Semi-Sorted Bits per Item at ฮต = 0.1%
b = 1 (Standard 2-Choice)50.0% (0.500)+1 bit15.29 bits21.93 bitsโ€”
b = 2 Slots/Bucket84.0% (0.840)+2 bits10.29 bits14.25 bits13.06 bits
b = 4 Slots/Bucket (Canonical)95.5% (0.955)+3 bits10.10 bits13.58 bits12.53 bits
b = 8 Slots/Bucket98.0% (0.980)+4 bits10.86 bits14.25 bits13.23 bits
Standard Bloom Filterโ€” (p0 = 0.50)ร— 1.4427 factor9.58 bits14.38 bitsโ€” (No deletions)

Because a Bloom filter scales multiplicatively as 1.4427 log2(1/ฮต) bits per item whereas a (b = 4) cuckoo filter scales additively as (log2(1/ฮต) + 3) / 0.955 bits per item, cuckoo filters use less memory than Bloom filters whenever ฮต < 3% (and under Semi-Sorting compressionโ€”which sorts the 4 fingerprints inside each bucket and encodes their high-order bits via a 12-bit permutation index, saving 1 bit per itemโ€”whenever ฮต < 2%).

Semi-Sorting Compression and Theoretical Refinements

In a 4-slot bucket (b = 4), the order of the 4 fingerprints within the bucket carries no semantic meaning. By sorting the four f-bit fingerprints in each bucket and grouping their 4 most significant bits into one of the (16 + 4 โˆ’ 1 choose 4) = 3,876 monotonic 4-tuplesโ€”which fits inside a 12-bit table index instead of 4 ร— 4 = 16 bitsโ€”Semi-Sorting saves 4 bits per bucket (1 bit per item), lowering the cost to (log2(1/ฮต) + 2) / 0.955 bits per item.

From a theoretical perspective,David Eppstein (2016) proved that because partial-key cuckoo hashing restricts the alternate bucket difference i1 โŠ• i2 to the 2f values of h2(ฯ„), high-probability insertion ensures hold rigorously when the fingerprint width satisfies f = ฮฉ((log n) / b). When b = 4 and f โ‰ฅ 8 bits, empirical and asymptotic analyses confirm 95.5% occupancy across multi-billion-key tables in network routers, consistent hashing directory caches, and distributed database storage engines alongside the quotient filter and Xor filter.

Frequently Asked Questions

What happens if more than 2b = 8 keys collide on both the primary bucket i1 and the f-bit fingerprint ฯ„?

Because two keys with the same primary bucket i1 and the same fingerprint ฯ„ also share the precise same alternate bucket i2 = i1 โŠ• h2(ฯ„), at most 2b (8 for b = 4) such identical-fingerprint keys can fit into buckets i1 and i2 combined. To keep the probability of > 2b identical (i1, ฯ„) collisions negligible across n keys, the total number of distinct (i1, ฯ„) pairs m ยท 2f must outscale n, which requires f = ฮฉ((log n) / b) bits (typically f โ‰ฅ 8 bits for b = 4).

Why can a Cuckoo Filter not use f = 0 or omit fingerprints altogether?

Even if false positives did not matter, partial-key cuckoo hashing requires storing a non-zero fingerprint ฯ„ in each slot so that an evicted item can compute its alternate bucket i2 = i1 โŠ• h2(ฯ„), and it reserves the value ฯ„ = 0 to mark unoccupied slots (re-mapping any key whose hash produces 0 to ฯ„ = 1).

References

  1. Fan, B., Andersen, D. G., Kaminsky, M., & Mitzenmacher, M. D. (2014). "Cuckoo Filter: Practically better than Bloom." Proceedings of the 10th ACM International on Conference on Emerging Networking Experiments and Technologies (CoNEXT '14), 75โ€“88. https://doi.org/10.1145/2674005.2674994
  2. Pagh, R., & Rodler, F. F. (2004). "Cuckoo hashing." Journal of Algorithms, 51(2), 122โ€“144. https://doi.org/10.1016/j.jalgor.2003.12.002
  3. Dietzfelbinger, M., & Weidling, C. (2007). "Balanced allocation and dictionaries with tightly packed constant size bins." Theoretical Computer Science, 380(1โ€“2), 47โ€“68. https://doi.org/10.1016/j.tcs.2007.02.054
  4. Eppstein, D. (2016). "Cuckoo filter: Simplification and analysis." Proceedings of the 15th Scandinavian Symposium and Workshops on Algorithm Theory (SWAT 2016), LIPIcs Vol. 53, 8:1โ€“8:12. https://doi.org/10.4230/LIPIcs.SWAT.2016.8
  5. Breslow, A. D., Zhang, D. P., Greathouse, J. L., Jayasena, N., & Tullsen, D. M. (2016). "Horton tables: Fast hash tables for in-memory data-intensive computing." Proceedings of the 2016 USENIX Annual Technical Conference (USENIX ATC '16), 281โ€“294. https://doi.org/10.5555/3026959.3026986
๐Ÿงฌ Support Open Science
Explore interactive science games on LowKey Games or browse scientific apparel & accessories in the CRV Science Shop.
๐Ÿ’ก Spot an inaccuracy or have primary literature to expand this article?
Submit a citation or revision note using your shared CRV Science / LowKey Games profile ID.
Suggest Revision