Finding Neighbors Inside the Eligible Corpus

Follow equally selective filters through a bounded graph walk and cluster routing, then choose a search plan against an exact eligible baseline.

Two tenants each own one third of a corpus. For one tenant, the nearest documents sit beside the query. For the other, every eligible document lies farther away, beyond the first region the search inspects. A planner that sees only the fraction of matching documents treats these queries alike. Their access paths may need very different work.

The tenant-filter article already shows how truncating global candidates can starve a filtered answer. This chapter goes underneath that boundary: which vertices or clusters does an index let a query reach, what does a predicate change about that navigation, and when should the planner stop trying the approximate path?

Locate those access paths on the primer’s search-system map. Its answers and quality vocabulary separates the eligible population, inspected candidates and exact-neighbor fidelity used below.

We continue the synthetic engineering-document service from the identity chapter. The baseline remains 50,000 documents in one region, 10 queries/s and 20 updates/s; these are scenario inputs, not measured capacity. The new requirement is to serve equally selective filters with different geometric placement, then a conjunction of tenant and document kind. Reading time covers prose; reserve additional time for the exercises.

Evidence boundary: All coordinates, graph edges, budgets and thresholds below are stipulated teaching inputs. The walk is a single-level FIFO graph mechanism, not a simulation or benchmark of HNSW, ACORN or a production planner. The inspected primary sources explain their own mechanisms; no engine experiment or benchmark reproduction is claimed.

The population tells you the answer, not the access path

A predicate is a condition that a record either satisfies or fails. At search snapshot S, let N be the number of live documents in the selected corpus and E be those satisfying the full query predicate. Define selectivity here as the matching fraction s = |E| / N. A smaller s means fewer matches. Always name the denominator: a fraction of a service’s named collection, or namespace, differs from a fraction measured after tenant restriction. Neither scope is automatically one physical shard.

The tenant comes from trusted identity context, not an arbitrary request value. Snapshot eligibility combines that tenant with live state and additional filters. A dense query selects one named vector field, here body, with exactly one vector per document in that field. Rank distinct documents by squared Euclidean distance ascending, then doc ID ascending. Adding the stored title vector in the earlier chapter did not change this query’s score. Multi-field aggregation remains a separate contract.

The exact eligible oracle enumerates all of E at S, calculates every selected-field distance and takes the first min(k, |E|) documents under that total order. An approximate result R has eligible-neighbor recall |R ∩ oracle| / |oracle| when the oracle is nonempty. For an empty oracle, recall is N/A and the required result is empty. Every returned document must separately satisfy eligibility. Exact-neighbor fidelity measures agreement with distance ranking; judged relevance and freshness answer different questions.

For a tiny E, enumerating the eligible IDs with an attribute index and computing their distances can be a strong plan. An attribute index maps values to matching records; a bitmap represents membership with bits and can combine predicates with set operations. Enumeration is work too: reading and intersecting these structures can dominate a very small distance scan. The pgvector v0.8.6 filtering documentation recommends starting with a filter-column index and explicitly says small matching fractions can work well with exact search. That is a useful counterpoint to treating every prefiltered scan as too slow.

An approximate global path instead finds promising vectors in the whole corpus and filters those candidates. Its effort depends on where matches occur along that path. In ACORN §3, Patel and colleagues distinguish selectivity from query correlation: eligible vectors may cluster near or far from the query compared with a randomly selected set of the same size. This is a geometric property, not just a count. Below, “near” and “far” are descriptive toy placements; we do not estimate the paper’s formal workload correlation statistic.

Before reading the trace, predict this: if two masks each retain four of twelve documents, must a four-vertex walk find the same number of matches? If it later finds k matches, has it necessarily found the nearest eligible k?

Save a graph small enough to inspect completely

Replace the service’s large vectors with twelve two-dimensional body vectors for this exercise only. The query is (0,0), all rows are live at S, and distance is x² + y². IDs are new to this chapter. Cluster membership and directed outgoing edges are saved inputs, not inferred from geometry. incident = 1 marks the second predicate.

doc_idxyclusterincidentoutgoingdistance
2110C01[22,23,25]1
2201C00[24]1
2320C00[27]4
2402C00[28]4
2530C11[26,29]9
2603C10[30]9
2740C10[31]16
2804C10[32]16
2950C21[31]25
3005C20[32]25
3160C21[]36
3206C20[]36

Run two alternative snapshots: Near assigns tenant A to [21,22,23,24]; Far assigns A to [29,30,31,32]. All other rows belong to B. Each snapshot has twelve live documents and four eligible A documents, so both selectivities are 4/12 = 1/3. Labels change between alternatives; the query, vectors and saved edges do not.

Our walk follows an explicit rule. Initialize a first-in, first-out queue with entry 21 and mark it discovered. Pop a vertex, calculate its distance, then enqueue its not-yet-discovered outgoing neighbors in the saved order. Keep walking through nonmatching vertices, but admit only eligible popped IDs to the result pool. Stop after B pops or when the queue is empty. Finally sort the eligible pool by (distance, doc_id) and take k. One pop costs one distance evaluation; adjacency and predicate work are additional counters.

This FIFO rule is deliberately simple enough to reproduce by hand. Real graph search has its own candidate queues, levels, neighbor selection and stopping rules. The point is to identify what a finite traversal inspected, rather than hide an unexamined algorithm behind the name HNSW.

steppoppednewly queued
121[22,23,25]
222[24]
323[27]
425[26,29]
524[28]
627[31]
726[30]
829[]
928[32]
1031[]
1130[]
1232[]

For B=4, the distance-evaluated IDs are [21,22,23,25]. Enqueuing 29 is not evaluating or returning 29: it is still waiting when the budget ends. Near returns [21,22], exactly its k=2 oracle. Far returns [], although its oracle is [29,30]. Both results obey the predicate. Only one achieves full eligible-neighbor recall.

The same eligible count, a different place on the saved path

Near mask: 21,22,23,24

  1. B=4 inspects 21,22,23,25

    Three popped documents match A. The pool contains both exact nearest eligible IDs.

  2. Return 21,22

    Distances tie at 1; ascending doc ID fixes their order. Recall is 1.

Far mask: 29,30,31,32

  1. B=4 inspects the same four IDs

    None matches A. The path has queued 29 but has not evaluated it. Recall is 0.

  2. B=10 reaches 29 and 31

    Two matches are enough to fill k, but unseen 30 is closer than 31. Recall is 1/2.

Synthetic FIFO walk at snapshot S, entry 21, k=2. Four eligible documents in each variant. Enqueued IDs remain unexamined until popped. The tables give the complete graph and trace.

The second Far lane exposes a more subtle stopping boundary. At B=10, the result is [29,31], with distances 25 and 36. Doc30 also has distance 25 and belongs before doc31; it is not popped until step 11. Having enough matches did not establish the nearest eligible answer. Increasing this toy budget to 11 repairs the result. No particular production budget follows from that calculation.

caseeligible IDsoraclegraph resultrecallgraph distances
Near[21,22,23,24][21,22][21,22]14
Far[29,30,31,32][29,30][]04
Far-enough[29,30,31,32][29,30][29,31]1/210

Bridges are navigation, not disclosure

In Far, entry 21 and intermediate 25 belong to B. Following their edges lets the walk reach A’s doc29. If a different rule rejected a nonmatching vertex before expanding its outgoing edges, it would stop at entry 21 even with a larger budget. Increasing a queue budget cannot restore edges that the traversal rule never follows.

A trusted search engine may use nonmatching adjacency or vector metadata internally under its declared isolation policy. That does not authorize disclosing the corresponding document contents. The application checks current-policy authorization at a defined decision point before returning content or forwarding it to an external reranker or generator. An old snapshot match is not proof of current permission. This model assumes a trusted policy lookup at that point and does not promise that a policy cannot change afterward. It also does not analyze timing side channels or design a tenant-isolation protocol.

Cooperate with the predicate while navigating

Two mechanisms can reduce travel through unhelpful regions. They pay for that information in different places.

Route to clusters that may contain matches

A cluster index groups vectors, then uses representatives such as centroids to select groups to inspect. For this toy, a centroid is the arithmetic mean of its cluster’s saved coordinates. Its distance helps rank clusters; it is not a lower bound on every member’s distance.

clustermemberscentroid_xcentroid_ycentroid distance
C0[21,22,23,24]0.750.751.125
C1[25,26,27,28]1.751.756.125
C2[29,30,31,32]2.752.7515.125

Suppose an exact, snapshot-consistent attribute summary says which clusters contain at least one match. An unfiltered one-cluster router chooses C0, yielding no Far matches. A predicate-aware router excludes C0 and C1 and chooses C2. Evaluating all four eligible members there yields Far’s exact [29,30] in four document-distance evaluations, plus summary reads and centroid work. Near similarly selects C0 and gets [21,22]. Exactness happens here because each eligible set is wholly contained in its one selected cluster. On another corpus, stopping after one matching cluster remains approximate unless a valid bound proves other clusters cannot improve the result.

turbopuffer’s January 2025 native-filtering account describes this cooperation: find nearby clusters containing matches, then evaluate matching candidates inside them. Its attribute structures include cluster-level summaries and exact within-cluster bitmaps. The described LSM keys use (attribute_value, cluster_id) with sets of local IDs; the attribute index reacts when an ANN address changes. That is evidence for the described older design, not a specification of the in-progress v3 layout.

Cluster summaries are useful but coarse. “Some row in C0 satisfies P” and “some row in C0 satisfies Q” do not imply that the same row satisfies P AND Q. Intersecting cluster-level bitmaps produces candidate clusters. Intersecting exact row membership, or checking the full predicate, resolves false positives. A missing true match in a supposedly safe summary can instead cause an incorrect exclusion, so maintenance and snapshot consistency matter.

Recover useful graph neighborhoods

ACORN §5 targets search over a predicate subgraph: vertices passing the predicate and the edges between them. Simply deleting nonmatching vertices from a graph can remove useful routes, as the bridge example shows. ACORN changes how useful neighborhoods are supplied, rather than assuming the surviving graph is always navigable.

ACORN-γ expands candidate neighbor lists during construction and uses predicate-agnostic pruning to control storage. During search it filters neighborhoods to matching vertices; its compression-compatible lookup can examine selected two-hop neighbors to recover pruned connections. ACORN-1 moves neighbor expansion to query time, considering one-hop and two-hop neighbors before predicate filtering and truncation. “Two-hop” means following a neighbor’s adjacency list; that internal lookup need not reveal its document contents. These are descriptions of the inspected paper’s mechanisms, not configuration instructions for every implementation.

The paper also includes a prefilter fallback below a configured minimum selectivity. Its §7.2 compares optimized exact prefiltering, an over-searching postfilter baseline, and separately configured ACORN variants. Those choices matter when interpreting the results: a comparison against a postfilter baseline that asks for only k global candidates is a different experiment. No universal runtime or connectivity guarantee follows from the tiny walk or from a paper’s evaluated datasets.

The August 2026 Qdrant study gives a concrete planner counterpoint. In its tested implementation, filterable graph edges are built per payload field, while query-time ACORN-1 expansion helps with gaps including AND predicates. The planner can choose a payload-index path for small eligible sets. In the described default configuration ACORN is opt-in; this is not a default inferred from the original paper. The study uses Qdrant 1.18.2, one million 96-dimensional image vectors, 500 queries per filter and serial execution on one machine. It reports mean server-side latency, not production p99. Its own-strategy results are vendor-authored and unreplicated here. Their teaching value is the separation of build work, query repair and fallback, not a database ranking.

A conjunction changes both the count and the geometry

The saved incident predicate matches [21,25,29,31]: four of twelve documents. Near’s tenant predicate also matches four, but their intersection is only [21]. Far’s intersection is [29,31]. You cannot multiply 1/3 × 1/3 without an independence assumption; the actual matching fractions are 1/12 and 2/12 = 1/6. The incident labels are associated with document placement, and the conjunction selects its own population.

Use these scenario inputs for the worked cases and exercises. “A IDs” defines the trusted tenant’s snapshot membership; none leaves it unchanged, while incident intersects it with the saved incident mask. Other documents belong to B.

scenarioA IDsextra predicatekB
Near[21,22,23,24]none24
Far[29,30,31,32]none24
Far-enough[29,30,31,32]none210
Guided[21,22,23,24]incident34
Independent[22,26,29,31]incident38
Empty[]incident30

Guided prediction: one eligible record

Use Guided. Enumerate the conjunction before computing distances. Compare a complete eligible exact scan with the B=4 walk; choose a first plan hypothesis. Include k=3 in the answer rather than silently changing it to one. Then answer Empty under its saved inputs.

Check the tiny-set plan and empty result
caseeligible IDsoraclegraph resultrecallgraph distances
Guided[21][21][21]14
Empty[][][]N/A0

Guided’s eligible exact scan calculates one document distance; the walk calculates four. Start with the exact-scan hypothesis if the attribute index enumerates the conjunction cheaply and completely at S. Both results contain only one document despite k=3. The oracle denominator is one, and exact-scan recall is 1. Empty requires no document distance calculation, returns [], and has N/A recall.

A pass names the intersection, IDs, total order, denominator and cheaper modeled distance count, then states what could overturn the plan. Expensive bitmap retrieval, scattered cold vector reads or concurrent workload contention could make the one-distance plan slower end to end. Distance count alone does not establish latency.

Independent problem: scatter the tenant, then restrict the kind

Use Independent: move A’s labels to [22,26,29,31], still four of twelve documents, add incident, raise k to 3 and give the walk B=8. First predict its result without looking at the answer. Derive the exact oracle, then explain what a cluster-level AND intersection can and cannot establish.

Choose a plan and rejected alternative. Stipulate a cumulative cap of ten document-distance evaluations for the initial path plus fallback, with separate implementation limits for memory and deadline. If you start with the walk, can a complete eligible scan fit afterward? Decide what response is allowed if the exact fallback cannot finish. Name one measurement and threshold that would change your plan choice.

Check the changed placement, conjunction and bounded fallback
caseeligible IDsoraclegraph resultrecallgraph distances
Independent[29,31][29,31][29]1/28

The tenant fraction remains 1/3; the incident fraction is 1/3; the conjunction fraction is 1/6. Doc22 and doc26 fail the incident predicate. The exact oracle has two distinct documents despite k=3, ordered by distances 25 then 36. The B=8 walk reaches only doc29. It returns an eligible result with half the oracle, not a correct fewer-than-k answer.

Both individual predicates have cluster summaries [C0,C1,C2]. Their coarse intersection therefore retains all three clusters, but C0’s tenant match is doc22 while its incident match is doc21; C1 similarly has doc26 versus doc25. Those clusters have no conjunction match. Exact row masks leave only doc29 and doc31 in C2. A complete eligible scan calculates two document distances and returns [29,31] with recall 1.

One defensible choice is direct eligible exact scan, rejecting the fixed B=8 walk because its saved result misses doc31 while computing more distances. If the walk ran first, a fresh two-distance fallback fits the stipulated cumulative cap: 8 + 2 = 10. This calculation deliberately does not credit reuse of doc29’s distance. It still assumes complete eligible enumeration, memory and remaining deadline permit completion. If any of those limits prevent an exact finish, use the application’s explicitly capped/degraded response contract or fail the request; do not claim exact completion or quietly omit the predicate.

A pass includes the intersection, oracle and tie rule, finite trace, false-positive cluster explanation, resource accounting, disclosure boundary and a falsifying measurement. For example, reconsider the exact plan if controlled end-to-end p95 exceeds the stipulated 40ms target while a predicate-aware plan reaches at least 0.99 eligible-neighbor recall for this filter shape within that target. This is a proposed threshold, not a measurement. An application requiring exact neighbors cannot accept 0.99 as its answer contract.

Defend the plan with more than a matching fraction

The planner needs estimates it can act on: eligible count for the whole conjunction, geometry under the actual query distribution, accessible cluster/graph neighborhoods, vector dimension, index availability and costs under current cache and concurrency conditions. Partial indexes or tenant partitions may help stable query shapes, but they add storage, build work and update responsibilities; arbitrary predicate combinations can be too numerous to index separately. The pinned pgvector iterative-scan section documents continuation until enough results or configured scan limits. Its strict ordering governs returned candidates’ distance order; it does not prove the global eligible oracle was found.

Keep at least these work categories separate when comparing plans:

WorkWhat to recordWhy a distance count misses it
CPU and distance evaluationCandidate IDs, dimensions, distance calls, cycles and queue workA contiguous exact batch can differ from scattered graph lookups.
Predicate and routingBitmap bytes/intersections, cardinality estimates, centroid scores and adjacency checksSearch can avoid vector distances while spending more on masks and navigation.
Reads and responseVector/projection bytes, cache state, dependency rounds and authorization checksInternal traversal does not make payload fetches or content disclosure free.
Index maintenanceUpdates to row/cluster memberships, extra graph edges, serialized writes and compactionQuery assistance may move work to ingest and increase storage pressure.
LimitsInitial and fallback work, cumulative deadline, memory and failure outcomeA fallback after a costly miss can exceed the resources available to the request.

Compare an approximate plan with exact eligible results at the same snapshot, field, predicate and total order; pgvector’s monitoring section explicitly recommends exact comparisons. Sample Near, Far, scattered and conjunction shapes separately. Report result count, eligible-neighbor recall, work, capped-query frequency and end-to-end latency distributions. Include updates and warm/cold conditions. Aggregating every filter into one recall or latency mean can hide the failing intersection.

For our tiny conjunction, the chosen first hypothesis is complete eligible enumeration followed by exact distance scoring. The rejected fixed-budget graph path has a concrete missing neighbor. For larger E, predicate-aware routing or graph expansion earns consideration; neither gets a free proof from selectivity. A production decision needs controlled measurements and declared approximation semantics.

Your exit artifact is a short plan note containing the chosen path, rejected alternative, exact eligible baseline, termination/fallback limits and a measurement threshold that would change the choice. Preserve that note when the workload changes. Doing less work and working faster explains why skipped work and CPU efficiency are separate. From durable write to searchable snapshot asks which versions the indexes and their summaries are allowed to represent together.

For selected reading, use pgvector v0.8.6 Filtering, Iterative Index Scans and Monitoring to resolve exact-small-set and finite-budget behavior; ACORN v1 §§3, 5 and 7.2 for correlation, neighborhood mechanisms and baseline configuration; the native-filtering account for cluster/row summaries and their maintenance; and Qdrant’s scoped August 2026 study for per-field edges, AND predicates and planner fallback. These selections answer different mechanism questions. Their performance figures have not been reproduced for our service.

Search-systems Ch 4/6
  1. 1 A Map of Search Systems 10m
  2. 2 When an Index Becomes Your Data Model 11m
  3. 3 Doing Less Work, and Doing Work Faster 15m
  4. 4 Finding Neighbors Inside the Eligible Corpus 15m
  5. 5 From Durable Write to Searchable Snapshot 15m
  6. 6 Paying for Retrieval Across Storage and Shards 18m