Stable Bloom Filter
Membership testing over an unbounded stream in bounded memory: old entries fade out probabilistically so the false-positive rate stabilizes instead of growing forever like a Scalable Bloom Filter.
How it works
A Scalable Bloom Filter handles an unbounded stream by growing memory forever. A Stable Bloom Filter instead fixes its memory (m cells, each holding a small counter up to Max) and continuously evicts old information to make room for new items.
On every add(): first d randomly chosen cells are decremented by 1 (regardless of what item they belong to), then the k hash-derived cells for the new item are set to Max. Because eviction happens on every insert whether or not the filter is "full," the fraction of cells at Max converges to a steady state rather than climbing toward 1.
The cost: this filter can produce false negatives. An old item can eventually be evicted and reported as absent, something a classic or counting Bloom filter never does. Larger d means faster forgetting (lower memory pressure, shorter memory); smaller d means items stick around longer before fading.
Interactive demo
API surface
| Operation | Description | Complexity |
|---|---|---|
| new StableBloomFilter(m, k, d?, max?) | Allocate m counter cells (0..max, default max=3) with k hash functions; d cells evicted per insert (default ~2% of m). | O(m) space |
| add(item): void | Decrement d random cells, then set the k derived cells to max. | O(k + d) time |
| has(item): boolean | True if all k derived cells currently equal max. | O(k) time |
| fillRatio(): number | Fraction of cells currently at max, converging to a steady state under sustained inserts. | O(m) time |
References
Original papers
- Approximately Detecting Duplicates for Streaming Data Using Stable Bloom FiltersFan Deng, Davood Rafiei · 2006
Library implementations
Real-world use cases
- Streaming duplicate detection over unbounded/infinite feeds (the original use case: web-crawl and click-stream dedup) in fixed memory
- Any long-running membership test where old entries should naturally "fade out" instead of being kept forever or evicted by an LRU policy