Skip to Content

Metadata Filtering (Pre-Filter vs Post-Filter)

When to use

Slice a vector index by structured criteria — tenant, document type, time-window — without losing recall.

Analogy

Library aisle + index card. You go to the right aisle (tenant: ‘acme’; type: ‘pdf’) and then read the index cards in that aisle. Pre-filter goes to the aisle first; post-filter skims the entire library and throws away non-acme results.

Data-flow diagram

  pre-filter  :  filter -> each matching -> ANN over subset
  post-filter :  ANN over all -> filter -> top-K

  pre-filter preserves recall; post-filter can return fewer than K

Deep explanation

Pre-filter: push structured predicates into the vector search; the ANN runs only on rows that match. Recall and latency stable. Post-filter: run ANN over the whole collection, then drop non-matching rows. Cheaper conceptually; prone to returning fewer than K matching items when filters are tight. Pick pre-filter for tight filters (5 percent of corpus matches); post-filter for very loose filters (90 percent matches).

Examples

Example 1

# pgvector: pre-filter via WHERE before ANN
SELECT id FROM chunks
 WHERE tenant_id = :tenant
   AND ts >= NOW() - INTERVAL '30 days'
 ORDER BY embedding <=> :query_vec
 LIMIT 5;

Pre-filter pushes metadata into the index plan — the ANN only scans matching rows.

Example 2

# vector DBs with server-side metadata filter
pinecone
results = index.query(vector=q, top_k=5,
    filter={'tenant':'acme', 'source_kind':'pdf'})

Server-side filter is one round-trip; client-side post-filter is two.

Example 3

# pattern to avoid: post-filter collapse
# 1) ann over all  -> 1000 candidates
# 2) filter -> only 12 left -- way less than K
# Fix: pre-filter to 1.5x K, then ANN over that subset

Pre-filtering to 1.5 times K before ANN guarantees you can return top K after filtering.

Common mistake

Post-filtering after ANN — the index returns 1000 candidates and most are dropped, returning only a few of the requested K.

Key takeaway

Pre-filter most of the time; it preserves recall and saves work. Post-filter only when filters are loose (<5 percent selectivity makes pre-filter less efficient).

Production Failure Playbook

Failure scenario 1: post-filter-collapse

Failure scenario 2: tenant-filter-no-isolation