0

Filtered Vector Search: What ACORN Fixes, and What Fixes ACORN

Dylan Couzon & Meina Ghafouri

·

July 27, 2026

Filtered Vector Search: What ACORN Fixes, and What Fixes ACORN

Filtered vector search breaks when metadata filters turn a healthy nearest-neighbor graph into scattered islands. HNSW’s m parameter controls how many links each point gets; at Qdrant’s default m=16, the collection we benchmark below averaged about 21 links per node on layer 0. Filter out 96% of the points and fewer than one link per node survives on average, so traversal gets stranded before it reaches the true nearest matches.

Qdrant repairs that damage in two places. ACORN patches a filter-blind HNSW graph at search time. Filterable HNSW repairs the graph at index time, by adding edges for indexed payload values. Both are available on the same collection, and they don’t cost the same.

ACORN earns its cost only on fields where Qdrant built no extra edges. We benchmarked both approaches on the same data: Qdrant on one machine, configured four ways, with no other engine measured.

The Two ACORNs

The ACORN paper (Patel et al., SIGMOD 2024) describes two algorithms. ACORN-gamma, renamed ACORN-W in the latest revision, drives the claim of “2-1,000x higher throughput at a fixed recall.” It expands neighbor lists during index construction, with reported build times 8.8x to 33.1x slower than plain HNSW.

ACORN-1 is the lighter variant: build a standard HNSW graph, then check neighbors of neighbors at search time when the filter removes too many direct ones. Qdrant implements ACORN-1, as a query parameter you opt into per request, with no index-time changes required.

The Graph Qdrant Builds Instead

Filterable HNSW, which our co-founder Andrey Vasnetsov described in 2019, builds the fix into the index. When a field has a payload index, Qdrant adds extra HNSW edges between points that share a value in that field, so a filtered query keeps a connected graph to traverse.

You pay for those edges at build time. Indexing one million points took 171 seconds without them and 448 to 560 seconds with them, a 2.6x to 3.3x cost. ACORN-1 asks for nothing at build time and pays at query time instead.

Those edges follow two rules. First, Qdrant skips them on fields whose value groups are big enough that the main graph keeps them connected. Second, Qdrant builds them per field, never per combination, so an AND filter lands on an intersection that no single field’s edges cover.

ACORN aims at both gaps from the query side, as one option behind the query planner, alongside full scan, retrieval straight from the payload index, and filterable HNSW.

The Benchmark

We benchmarked four strategies on one million deep-image-96 image vectors, with keyword filters from 20% down to 0.012% selectivity and recall@10 scored against exact brute force. Most filters are independent of the vectors; one 10% filter is correlated with them.

The plain graph checks the filter during traversal and discards points that fail; it’s the control, with extra edges switched off. The second strategy forces ACORN on that same graph. The third is filterable HNSW. The fourth is Qdrant’s default planner, which stacks all three tools: extra edges, ACORN, and the payload-index fallback. Latency is mean server-side query time. The reproduction kit has the full methodology.

Every number below was measured on Qdrant v1.18.2, July 27, 2026.

Single Filters: Edges Beat the Patch

Recall@10 at hnsw_ef=64, with mean server-side latency. hnsw_ef, shortened to ef below, is the per-query search budget: how many candidates the search keeps in flight. Selectivity is the measured fraction of points passing the filter.

Filter (selectivity)Plain graphPlain graph + ACORNFilterable HNSWPlanner + ACORN
One keyword (20%)62.9% @ 1.6ms98.9% @ 4.4ms94.8% @ 1.2ms100% @ 10.9ms
One keyword (10%)20.6% @ 1.7ms98.1% @ 4.3ms99.0% @ 1.1ms99.9% @ 8.5ms
One keyword (1%)0.1% @ 1.6ms67.7% @ 4.7ms99.8% @ 1.0ms100% @ 1.5ms
Correlated (10%)88.4% @ 1.7ms98.6% @ 3.5ms99.0% @ 1.2ms99.9% @ 7.2ms

The plain graph collapses as filters tighten. ACORN helps, but only up to a point: it pulls recall back at 2.1x to 2.9x plain-graph latency, then stalls at 67.7% on the 1% filter. That stall is a known ACORN-1 weakness, the one the RACORN-1 follow-up paper sets out to fix.

Where extra edges exist, they solve the problem earlier and cheaper. They hold 99.0% to 99.8% recall on the 10%, 1%, and correlated 10% filters at 1.0ms to 1.2ms. ACORN gets close on two, but needs 3.5ms to 4.7ms. Correlation lifts the plain graph to 88.4%, still short of the edges.

Bar chart of recall at hnsw_ef=64 on four single-field filters, with each bar's mean server-side latency, comparing plain graph, plain graph with ACORN, and filterable HNSW.

Recall@10 and each bar’s mean server-side latency at hnsw_ef=64 on the single-field filters. Extra edges hold the top recall at about 1ms; ACORN pays 3 to 4x that.

The 20% filter falls under the first rule: its value groups are large enough that the main graph keeps them connected, so Qdrant skips extra edges. Recall still climbs from 62.9% to 94.8% because edges for other fields densify the shared graph. It is the only single-filter case where ACORN beats filterable HNSW, 98.9% against 94.8%, because this field has no edges of its own.

With ACORN enabled, the planner applies it when the filter passes 40% of points or fewer (the max_selectivity gate), and every filter here qualifies. Recall reaches 99.9% to 100%, at 7.7x to 9x filterable HNSW’s latency on the uniform 10% and 20% filters. Skip the option and you get the filterable HNSW numbers.

Double Filters: The Intersection Gap

The same four strategies at hnsw_ef=64, now with an AND filter over two keyword fields.

Filter (selectivity)Plain graphPlain graph + ACORNFilterable HNSWPlanner + ACORN
Two keywords (4%)0.1% @ 3.9ms95.2% @ 7.7ms63.7% @ 1.2ms99.9% @ 13.9ms
Two keywords (1%)0.0% @ 3.4ms72.7% @ 6.8ms70.8% @ 1.5ms100% @ 3.7ms
Two keywords (0.012%)0.5% @ 2.5ms0.6% @ 2.6ms1.8% @ 2.6ms100% @ 1.3ms

The AND filter breaks the plain graph outright. At 1% it returned about 1.4 of the 10 requested points, and raising ef to 512 doesn’t add a single one, because the traversal has already exhausted its disconnected island.

The 1% intersection is a tie. Both fields have full edge coverage, but their AND intersection doesn’t. ACORN’s 72.7% against filterable HNSW’s 70.8% sits inside build-to-build noise: rebuilds at the same settings moved ACORN’s recall between 70.7% and 74.1%.

The tie breaks when the search budget rises. At ef=512, filterable HNSW reaches 91.2% recall at 4.9ms, while ACORN needs 20.1ms to reach 90.3%. Spending a bigger search budget on a graph built for the filter is cheaper than repairing a filter-blind one at search time.

Recall versus server-side latency for four filtered-search strategies as hnsw_ef sweeps from 64 to 512.

Recall vs server-side latency on the 1% double filter, hnsw_ef swept from 64 to 512. Filterable HNSW reaches ACORN-level recall at roughly a quarter of the latency, while the planner holds 100% by switching strategy per query.

ACORN wins on the 4% intersection because neither field has extra edges. Under the first rule, both fields hold five values of 200k points each. The gap holds across the sweep: 99.6% against filterable HNSW’s 92.5% at ef=512.

At 0.012%, the right move is to stop using the graph. With roughly 120 matching points in a million, the plain graph reaches 0.5%, ACORN 0.6%, and filterable HNSW 1.8%; the benchmark pins all three to the graph. On defaults, the planner reads the payload index and returns 100% recall at 1.3ms.

The planner changes the outcome before the graph fully collapses. On the 1% intersection, it sent 29 of the 500 queries to the graph and 471 to the payload index, reaching 100% recall at the 3.7ms mean shown before.

Where ACORN Wins

ACORN wins when the queried field has no extra edges. That happened on two of the benchmark’s seven payload fields, both with value groups too large for extra edges. On the other five fields, ACORN never beat filterable HNSW by a defensible margin.

ACORN repairs traversal after filtering, especially for oversized value groups and strict intersections. A PostgreSQL study reports 71.6K filter checks for ACORN at 1% selectivity against 2.6K for plain traversal on a five-million-point OpenAI embedding set.

Three questions decide filtered search quality: what the index holds before the query arrives, what the search budget buys during traversal, and when the engine stops traversing altogether. ACORN answers part of the second one.

Create a payload index on every field you filter on, because that’s what makes the extra edges possible. Use the telemetry endpoint to check which paths your workload takes. If a filtered field falls under the first rule, turn ACORN on per query and measure.

The reproduction kit includes the pinned image digest, dataset checksum, frozen queries, ground truth, and build receipts. Re-run it against your Qdrant version rather than relying on these tables. To discuss your filtered-search setup, get in touch.

Get Started with Qdrant Free

Get Started