Drag the query point and switch metrics to see how the nearest neighbors change.
Measures the straight-line distance between two points. The concentric circles show equidistant zones — all points on the same circle are equally "far" from the query.
A metric is just a function that takes two vectors and returns a single number telling you how similar (or different) they are. Vector search is, at its core, "find the K vectors with the best metric score against my query." Everything else — indexes, clusters, graphs — is just bookkeeping to avoid computing this score against every vector in the database.
The metric you choose defines what "similar" means for your data. Two embeddings can be "near" under one metric and "far" under another — same data, different answer. That's why this choice happens before you ever build an index.
Try this: drag the query point near the origin and switch between Cosine and L2. Watch how Cosine cares only about which "direction" the query is pointing — points on the opposite side of the origin can be "close" under L2 but "far" under Cosine. That visual is the entire concept.
In Milvus, the metric is set per index via metric_type — L2, IP, or COSINE for dense vectors — when you create the index. Every search against that collection then uses the same function you just played with above. The single most reliable rule: use the metric your embedding model was trained with, which is listed on virtually every model card.
Two useful shortcuts. Most modern text-embedding APIs (OpenAI, Cohere, Voyage and most sentence-transformers) produce vectors meant for cosine similarity. And if your vectors are normalized to unit length, cosine and inner product return identical rankings — so IP on normalized vectors is a common, slightly cheaper stand-in for COSINE.
Use cosine similarity (metric_type COSINE in Milvus). Almost all modern text-embedding models — including OpenAI's text-embedding-3 family — are trained for cosine similarity. Because OpenAI embeddings are normalized to unit length, inner product (IP) gives identical rankings and is a fine alternative.
Cosine similarity measures only the angle between two vectors, ignoring their lengths. Inner product (dot product) rewards both alignment and magnitude, so a longer vector pointing in the same direction scores higher. On unit-normalized vectors the two are mathematically equivalent.
No. The metric is baked into the index at build time. To switch metrics you drop the index and rebuild it with a new metric_type. Scores from different metrics are also not comparable with each other, so don't mix them when post-processing results.
Speed is essentially identical — L2, IP, and cosine all cost one pass over the vector. Recall is where it matters: searching with a metric different from the one your embedding model was trained for silently degrades result quality, often dramatically.
Go deeper: read the Similarity Metrics documentation for the full list of metrics Milvus supports, including Hamming and Jaccard for binary vectors and BM25 for full-text search.
Side-by-side comparison of brute-force vs clustered search. Tune nprobe in real time.
Watch the multi-layer graph search step by step — from highway jumps to local walks.
See how PQ-in-RAM + full-vectors-on-SSD lets you search billion-scale datasets on a laptop.