Two-stage retrieval uses a cheaper or approximate representation to generate a broad candidate set, then reranks candidates with the authoritative full vector or a learned model. PostgreSQL expression indexes support half-precision, binary, normalized, or subvector first stages. Candidate depth is the critical bridge: too small loses recall; too large erases latency gains.
The corresponding HNSW expression index must use the same binary expression and bit_hamming_ops. Authorization must apply in the candidate stage and remain true at final access.
It can preserve the intended stage boundary and candidate limit when the planner might inline a CTE. Always inspect the plan. In iterative relaxed scans, materializing and adding a small expression such as distance + 0 for strict reordering may be required by some PostgreSQL/pgvector versions; follow current upstream guidance.
Sweep candidate depths such as 20, 50, 100, 200, and 500 with ANN effort. Compare final top-10 against exact full-vector search. Record stage latency, total latency, recall, buffers, and result count for each filter slice.
Generate and explain a two-stage pgvector query for [representation, metric, filters]. Include exact matching expression-index DDL, oversampling sweep, materialization decision, full-vector rerank, plan assertions, authorization, and held-out recall gates.
Verification contract: Compare final IDs with full exact search and reject any speed gain that violates the defined slice-level recall.