Try out vector search for yourself using this self-paced hands-on learning for Search AI. You can start a free cloud trial or try Elastic on your local machine now.
What makes a good vector store?
A vector store that achieves good performance without tuning is more valuable than one that requires expert tuning. In fact, our contention is a data store that can be coaxed to exceptional performance by an expert who spends a week hand-tuning it is less useful than one that beats it consistently out of the box. In other words, easily achieving good performance is a first class property, not a nice to have. We can see this clearly in our telemetry. The great majority of users will never tune the internals of vector search at all, and why should they: it is just an enabler for what they're trying to build.
This is the imperative behind features like auto-calibration. The system as a whole should look at your data and your quality target and choose good parameters for you. Indeed we think this is a win-win, since it has far more nuanced information available to it to make these choices than we expose.
To make "good performance" precise, it helps to name the three attributes that characterize any vector search system, because they trade off against one another and you can't talk about one without fixing the others:
- Performance: throughput (QPS), latency, and so on.
- Hardware cost: a fair comparison always holds cost fixed. It's trivial to buy your way to more QPS or better recall by throwing hardware at the problem; the interesting question is what you achieve per dollar.
- Search quality: recall, nDCG, and related measures of whether you're returning the right results.
The three form a frontier. Push one and, at fixed budget, you pay in another. Any honest comparison of approaches pins two down and measures the third. What we describe in this post is the mechanism we're introducing to pick quantization parameters for a fixed recall budget. It is a step on a longer journey towards a vector store that configures itself well across the board.
Why recall is the right quality metric for vector search
Search quality is tricky, because the "right" results depend on relevance labels you usually don't have at index time. So we lean on recall as a safe proxy. The argument is simple: recall measures how well the approximate index reproduces the results of exact search over the same embeddings. If recall is high, you have not degraded search quality relative to what the underlying model can do; you can be confident you’ve faithfully preserved the baseline. You might still wish for a better embedding model, we've got you covered, but that's a separate concern from the index not damaging what the model already gives you.
This is why controlling recall matters so much, and why you should be wary of any system that doesn't reliably control it. If a vendor can't control recall, they can silently degrade your search experience, achieving impressive QPS numbers while quietly returning worse results, and you'd have no way to know without a labeled evaluation set. The method in this post is about maximizing performance while keeping a firm, predictable grip on quality.
Why vector quantization parameters must be chosen at index time
What makes the problem genuinely hard is that vectors are quantized as they are indexed, so the parameters that govern quality (how many bits, how deep to rerank, whether to precondition) have to be evaluated before we've seen the data laid out in its final form. We can't index everything, measure recall, and iterate; by then the quantization is baked in.
So we need to estimate what we'll need from a small sample, cheaply and in advance. Fortunately the Elasticsearch gives us natural moments to do this: segment merges are exactly such an opportunity. When segments are combined we have to rewrite the data anyway and can assess the data and (re)choose parameters. And as we'll see, models fit to small random samples give excellent estimates of the quantities we actually need to control. They’re typically good enough to set parameters once, with a small margin, and trust them as the index grows.
How vector quantization affects nearest-neighbor recall
With that motivation in place, let's start to dig into the details.
Vector quantization is a critical component for making approximate nearest-neighbor (ANN) search affordable at scale; it's an area we've innovated in the past. Instead of storing and comparing full-precision embeddings, we store a lossy, compressed representation and search over that. The catch is the one above: lossy representations move distances around, so the "nearest" neighbors under quantized distances are not always the true nearest neighbors and recall suffers.
The standard fix is to over-retrieve and rerank. We use the cheap quantized distances to pull back the top candidates, then recompute exact distances for those and keep the best . As long as the true top- are present somewhere in the retrieved top-, reranking recovers them exactly.
Reranking isn’t free, we have to fetch high precision vectors from disk. However, we can precisely characterize the performance of reranking based on hardware characteristics alone. This reframes the whole problem. The question is no longer "how much does quantization distort distances?" in the abstract, but something which relates back to the attributes we care about:
Given a quantization scheme with some error magnitude, and a rerank budget of candidates, what recall@ should we expect. As an immediate consequence, what is the cheapest set of parameters that hits our recall target?
This post derives a model that answers exactly that. The core of it is a single, surprisingly clean idea: if we can characterize the distribution of distances to the -th nearest neighbor, and we have a model of the quantization error distribution, then we can compute expected recall after reranking in closed form (up to a one-dimensional integral). Everything else – bit counts, rerank depth, whether to precondition – becomes a search over a model we can fit cheaply from a small sample, instead of an expensive empirical sweep over full indices built with those parameters.
We build it up to this in three stages: the geometry of nearest-neighbor distances, the scaling law that falls out of it, and then the recall model that ties quantization error to recall given a reranking budget. Be warned, the following gets a little bit involved, but to give you intuition about what is happening see the video below.

Illustration of how quantizing and rerank affects recall
Quantization error vs. the nearest-neighbor distance gap
Fix a query and rank the database vectors by their true distance to it: , so is the distance to the -th nearest neighbor. Reranking the top succeeds for the true -th neighbor whenever it is not pushed past rank by quantization noise.
Two competing quantities govern this:
- The quantization error that is essentially fixed for a given scheme and dataset: it depends on the embedding dimension, the vector distribution, and the number of bits, but not on how big the index is.
- The criticality gap , which is the distance between the -th and the -th nearest neighbor. This is the margin we have to absorb error. Crucially, it shrinks as the index grows: pack more vectors into the same region and neighbors crowd together.
There’s a detail here we’ll gloss over for the sake of presentation: for IVF style indices, we’re quantizing the residual from a cluster’s centroid. This does in fact couple the quantization error to the index size, but we can handle it much the same way we handle the distance to the -th nearest neighbor.
For reranking to recover the recall lost to quantization, we need the error to only rarely exceed the gap. If we can write down the distribution of and the distribution of the error, we can make that statement quantitative. The first job is to estimate the distribution of nearest-neighbor distances.
Deriving the nearest-neighbor distance distribution
Real embeddings don't fill their ambient space; they concentrate on a lower-dimensional manifold. Near a query, though, we can make a mild local assumption: in a small neighborhood around the query, the data density is roughly uniform. Here is the intrinsic dimension of the manifold; it is unknown and generally far smaller than the embedding dimension. How to estimate it is the subject of Section 4.
Let be the vectors falling in , modeled as i.i.d. uniform on , and define the distance from to its nearest neighbor:
To get the distribution of we use the standard order-statistics trick: rather than ask where the minimum is, ask for the probability it exceeds some radius . The event is exactly the event that every point lands outside the -ball centered on the query .
A single point lands inside with probability equal to the ratio of the ball's volume to the region's volume
where is the volume of the unit -ball. (We assume is large enough that the relevant is small, so the ball doesn't spill outside and boundary effects are negligible.) Because the points positions are assumed to be independent, the survival function is
What we're really interested in is how R behaves on average. To compute this, we use the identity that the expectation of a non-negative random variable is the integral of its survival function, . Evaluating this with (2) gives the headline result:
(The exact integral carries an extra factor; it's an constant that we can fold into a fitted coefficient later, so we drop it here.)
Glacial scaling: why neighbor distances barely change as your index grows
It is interesting to consider what this formula tells us about how distances change with dataset size: . The exponent is , and in high intrinsic dimensions that is a very small number. This is a property the method leans on, so it's worth plugging in some numbers:
- If then doubling multiplies by , so distances drop by ~30%.
- If then doubling multiplies by , so distances drop by a little over 1%.
In high dimensions, neighbor distances barely move even if you add a lot of data; call it glacial scaling. It's the reason we can choose quantization parameters once from a tiny sample, with a small safety margin, and trust them to remain valid even after the index grows substantially before the next re-quantization.
Expected distance to the k-th neighbor and the criticality gap
We actually care about the whole sequence of order statistics , , not just the minimum. There's a simple way to get them.
Map each radius to the cumulative volume it encloses by defining
By (1), each is exactly the probability of landing within radius , so the are uniform on . The order statistics of uniforms are textbook: the -th smallest of uniforms follows a Beta distribution,
Inverting the volume map, , gives the scaling of the -th neighbor distance:
That's all we need for the expected gap:
The last form is the intuitive one: the gap between the -th and -th neighbors is the distance to the -th neighbor, scaled by . Widening the rerank depth relative to opens the gap; higher intrinsic dimension closes it (the exponent pushes toward 1).
Why the expected gap is sufficient to predict recall
Working with an expectation is only legitimate if the gap doesn't fluctuate wildly around it. It doesn't because concentration of measure saves us. Applying the delta method to and using from the Beta distribution, a little algebra gives
So the coefficient of variation is about . For any reasonable intrinsic dimension this is negligible, which justifies modeling only the expected distances. (If you're worried about the delta method approximation, you can check the results numerically: the delta-method variance and the resulting coefficient of variation match the exact expressions to several significant figures.)
Extending the model to cosine similarity and inner product search
The derivation is for the Euclidean metric, but the other common metrics reduce to it:
- For cosine similarity, the equidistant surface is the intersection of a sphere around the query with the unit sphere. This is called a hyperspherical cap, whose volume scales as for small . Therefore, the analysis carries over unchanged up to constants, with the dimension reduced by one.
- For MIPS (maximum inner product), some extra care is needed, because nearest neighbors aren't confined to a compact region. A distant vector can still win on inner product if its norm is large enough, so the gap is really governed by the tail of the norm distribution. However, there is a clean fix, which is to use the Neyshabur–Srebro transformation. This lifts vectors onto a unit hypersphere in dimensions. After this operation, it's just the cosine case.
Fitting intrinsic dimension and scale from a small sample
Equation (3) has a known functional form but two unknown parameters: the intrinsic dimension and the scale . Both are easy to fit, and it's more convenient to fit them from raw neighbor distances than from gaps directly.
Sample several subsets of database vectors of sizes and a set of query vectors . For each query and each subset, measure , the distance to the -th nearest neighbor of within . Taking logs of the scaling law linearises it:
Specifically, this is linear in and , so ordinary least squares recovers and . Varying the subset size is what makes it possible to estimate : it's precisely the rate at which distances shrink with data volume. With the fitted parameters, the whole-index expected gap is
Figure 1 shows how well this fits in practice (and it’s remarkably good): predicted versus actual average distance to the -th neighbor, across a range of datasets and metrics, have between 0.996 and 0.999.

Figure 1 Goodness of fit of the average distance to the k-th nearest neighbor estimates. Each panel is a different dataset/metric; points are (actual, estimated) mean distances.
Modeling vector quantization error as Gaussian
With the nearest-neighbor distance model established, the second component is the quantization error distribution. For every metric we use, the quantized distance estimate differs from the true distance by an error that is a sum of many independent per-dimension contributions. By the Central Limit Theorem that sum tends to Gaussian, so we model the error as normal with a variance we estimate empirically:
where is the quantized distance estimate using -bit vectors and is the total number of (query, neighbor) pairs in our sample set. In other words: sample, quantize, measure the squared distance errors, average.
Figure 2 shows the empirical basis for the Gaussian assumption: measured quantization error densities against best-fit Gaussians across a variety of datasets. The fit is good, which is what lets the rest of the model stay analytic.

Figure 2 Quantization error density plots (query bits 1, doc bits 1) with the best-fit Gaussian overlaid. The near-Gaussian shape is what the CLT argument predicts.
We could stop here and take a minimax view: threshold the probability that the -th and -th neighbors swap, using the expected gap (4) against the error scale . But that controls a worst-case event, and what we actually want to control is average recall. The outcome would be overly conservative quantization parameters and we'd pay some performance. The next section estimates expected recall properly.
Predicting expected recall after reranking
Combining the distance model and the error model gives a closed-form estimate of expected recall after reranking. Model the noisy distance of the -th true neighbor as a Gaussian centered on its true distance:
The -th neighbor survives reranking, i.e., lands in the retrieved top , if fewer than other vectors have a smaller noisy distance. Condition on and count the competitors closer than :
Then the probability of recalling neighbor integrates over where its own noisy distance lands:
The terms of are independent Bernoullis but not identically distributed, since every neighbor sits at a different true distance , so each has its own probability of intruding on the top- set:
with the standard normal CDF. This makes a Poisson-binomial variable. Since we sum many of them (because ), the Lyapunov CLT applies and we approximate
with the standard Poisson-binomial moments
The survival probability then has a clean closed form:
This is where the two halves of the post so far finally meet. We don't need to know the individual because the manifold scaling law from Section 3 supplies them: . So the moments become explicit sums over ranks, which we truncate at a safe cutoff (say , since distant neighbors contribute negligibly):
Finally, average recall@ given rerank depth sums the per-neighbor recall over the top :
Here is the standard normal density. Each integral is smooth and one-dimensional, so Gauss–Legendre quadrature evaluates it in microseconds. The entire recall prediction for a set of candidate parameters costs a handful of quadrature evaluations, not index build and benchmark run.
Figure 3 validates the end-to-end model: predicted average recall against measured recall across many parameter settings and multiple datasets has .

Figure 3 Estimated versus actual average recall across a range of parameter settings and datasets. Points stay close to the ideal diagonal.
How the recall model selects vector quantization parameters
With a fast recall predictor available, parameter selection becomes a cheap ordered search. Given a target recall and a rerank budget (typically expressed as a multiple of ), we can find the minimum document and query bit counts, and other knobs, that clear the target. There are a few things to note that are practically important:
- Glacial scaling gives us some safety because moves so slowly with for even moderate intrinsic dimension. A small margin in the calculation means the chosen parameters stay valid if a lot of vectors are added before parameters are restimated.
- Small is the worst case if is a fixed multiple of . The gap \mathbb{E}[R_{(k)}]( is smallest for small so if a parameter choice satisfies the recall target at then it will for larger will too.
- We can treat quantization as a black box because the error model only needs the empirical error variance. This means we can test any configuration, including preconditioning, the same way and we can simply order candidate parameter tuples by increasing index and query cost, and stop at the first choice that hits the target recall. For tuples of (query bits, doc bits, rerank depth, precondition) a sensible search sequence increases query precision first, then document precision , , , , , , , , and each combined (via an outer product ) with rerank depths like and precondition , exiting as soon as the target is met.
Results: auto-selected quantization parameters and recall across datasets
In this section, we discuss the results of the initial experiments on the end-to-end behavior. We’ve made some further refinements as part of the work to fully integrate with Elasticsearch that we discuss in our other post.
The table below shows auto-selected parameters targeting recall 0.97, measured with brute-force search, so the number reflects loss due to quantization alone (64 query clusters, targeting document clusters of size 384, which matches the settings of DiskBBQ).
| Dataset | Query bits | Doc bits | Precondition | Depth | Recall |
|---|---|---|---|---|---|
| FiQA E5 small | 4 | 2 | false | 30 | 0.97 |
| FiQA arctic | 2 | 2 | false | 30 | 0.95 |
| FiQA GTE | 2 | 1 | true | 30 | 0.98 |
| MNIST | 3 | 1 | true | 30 | 0.99 |
| Fashion MNIST | 3 | 1 | true | 30 | 0.99 |
| Quora E5 small | 2 | 2 | false | 30 | 0.99 |
| Quora arctic | 2 | 1 | false | 30 | 0.97 |
| Quora GTE | 1 | 1 | false | 30 | 0.98 |
| Dbpedia E5 small | 4 | 2 | false | 30 | 0.99 |
| Dbpedia arctic | 2 | 1 | false | 30 | 0.94 |
| Dbpedia GTE | 2 | 1 | false | 30 | 0.96 |
| Wiki Cohere | 2 | 2 | false | 30 | 0.99 |
| Hotpot E5 small | 4 | 2 | false | 30 | 0.97 |
| Hotpot GTE | 2 | 1 | false | 30 | 0.96 |
| Glove 100 | 4 | 2 | false | 30 | 0.87 |
| Glove 200 | 4 | 2 | false | 30 | 0.89 |
| SIFT128 | 4 | 4 | false | 20 | 0.99 |
There are a few things worth highlighting:
- The recall is very sensitive to rerank depth. This is why we nearly always end up choosing the maximum depth available: a step up in rerank depth from 20 to 30 is typically what pushes us to hit the recall target for fewer bits and we prefer fewer bits. In the real system, we tuned this behavior based on a more representative reranking cost.
- Glove underperforms partly we approximate the query distribution with random samples from the corpus, but Glove is also less well characterized by the model than the other datasets. A plausible explanation is that the approximately uniform local density assumption from Section 2 is less reliable for Glove embeddings, which would show up as higher recall variance between queries. However, Glove embeddings are not representative of the actual vectors we need to store.
- The FiQA GTE preconditioning choice is a knife-edge case: preconditioning produced only a tiny expected recall improvement, but the prediction sat right at the recall cutoff and allows us to drop the query from 3 to 2 bits. If we'd rather only keep preconditioning where its benefit is clear-cut, we can enforce a minimum uplift threshold. This sort of fine-tuning of the decision logic leaves all the heavy lifting to estimate recall unaffected.
Key takeaways: auto-tuning vector quantization from first principles
We presented a method to pick optimal quantization parameters to achieve a target recall. It rests on two models that compose cleanly:
- A geometric model of neighbor distances that follows from a local uniform density assumption. We use this to derive the nearest-neighbor distance, the glacial scaling law of the expected distance, and the expected distance profile . We show that fitting and by a simple log-linear regression to average distances in small random samples from the corpus gives an extremely accurate predictive model.
- A Gaussian quantization error model that is justified by the CLT. Its only parameter is an empirical variance we estimate by comparing quantized and raw vector similarities for a sample of the corpus.
Finally, we show that it is possible to feed the estimated distance model into a Poisson-binomial count of neighbors that intrude on the top- set. Applying the Lyapunov CLT the expected recall@ after reranking to depth falls out as a one-dimensional integral we evaluate by quadrature.
The outcome is an accurate () predictive model of recall as a function of the quantization parameters. Choosing quantization parameters then becomes an ordered search with a predictive model telling us if we’ve hit the recall constraint. And nicely one that also comes with a built-in argument (glacial scaling) for why the chosen parameters remain safe even when estimated from a relatively small fraction of the data.
We’ve built this entire mechanism into Elasticsearch using segment merges as an opportunity to reassess our quantization choices. Aside from the peace of mind this brings (that you’ll achieve good recall whatever vectors you throw at it), it also allows us to chose near optimal parameters from a performance perspective. This closes the loop on our original objective: near optimal performance out of the box, at least as far as quantization goes. We’re pretty excited about the advantages that model based tuning can bring to vector search and look forward to sharing other work we have in this direction in the near future.




