---
title: "Bloom filter"
description: "A Bloom filter is a space-efficient probabilistic data structure used to test whether a value might be in a set, with no false negatives but a small, tunable rate of false positives."
canonical: "https://motherduck.com/glossary/bloom-filter/"
related:
  - title: "DuckLake Architecture Deep Dive"
    url: "https://motherduck.com/blog/ducklake-architecture-deep-dive/"
  - title: "DuckDB SQL | MotherDuck Docs"
    url: "https://motherduck.com/docs/sql-reference/duckdb-sql-reference/"
  - title: "Analyze JSON Data Using SQL and DuckDB"
    url: "https://motherduck.com/blog/analyze-json-data-using-sql/"
---

# Bloom filter

> A Bloom filter is a space-efficient probabilistic data structure used to test whether a value might be in a set, with no false negatives but a small, tunable rate of false positives.

## Overview

A Bloom filter answers one narrow question very cheaply: "could this value be in the set?" It never produces a false negative — if it says a value is *not* present, that's guaranteed true — but it can produce false positives, occasionally saying a value might be present when it isn't. In exchange for that small imprecision, a Bloom filter uses far less memory than storing the actual set of values, and both inserting and checking membership are extremely fast.

## How It Works

A Bloom filter is a bit array combined with several hash functions. Adding a value sets the bits at the positions its hash functions point to; checking a value tests whether *all* of those bit positions are set. If any of them are unset, the value is definitely absent. If all are set, the value is probably present — possibly because other values happened to set the same bits.

## Use Cases in Databases

Databases use Bloom filters to skip work: rather than doing an expensive lookup or scan, a cheap Bloom filter check can rule out a match with certainty and avoid the expensive path entirely. This is common in join processing (skip probing a hash table when the filter says a key can't match) and in file/block pruning (skip reading a block whose Bloom filter proves it can't contain a filter value).

## DuckDB and Bloom Filters

As of DuckDB 1.2, DuckDB reads and writes **Parquet Bloom filters** transparently. When writing Parquet, DuckDB automatically builds a Bloom filter per column chunk for dictionary-encoded columns; when reading, if a query filters on an equality predicate (`WHERE customer_id = 42`), DuckDB probes each row group's Bloom filter first and skips row groups the filter proves can't contain a match — before even looking at the row group's zone map or data.
