Qdrant
A Rust-native vector database with payload filtering, HNSW indexes, and distributed consensus.
Qdrant is a server-mode vector database written in Rust that pairs HNSW or scalar-quantized indexes with arbitrary JSON-style payload filters. It supports single-node embedded use, a replicated cluster mode (Raft), and a sharded cluster mode. Storage is split into vectors, payload, and an HNSW index, all on disk.
Filter + vector in one query
Each vector carries a JSON payload. Queries can combine a k-NN search with arbitrary filter expressions (e.g. price < 50 AND category = "books"). The index consults the payload store before scoring.
HNSW with quantization
Vectors are stored as f32 or as scalar-quantized int8. The HNSW graph is built once and updated incrementally; quantized mode cuts memory by 4x with a small recall loss.
Distributed consensus
In cluster mode, nodes replicate state via Raft. The query router forwards each request to the nodes that own the relevant shards, then merges the top-k.
Disk-backed by default
Vectors and HNSW indexes are mapped to memory-mapped files. Cold data lives on disk; warm data sits in the page cache.
The three on-disk stores
Qdrant separates its data into three stores. The vector store holds raw (or quantized) vectors in a columnar layout keyed by point ID. The payload store is a custom LSM-like key/value store keyed by point ID with field values. The HNSW store is the graph: lists of neighbor IDs at each level per point.
A search starts by evaluating the payload filter to a bitmap of candidate point IDs, then traverses the HNSW graph constrained to that bitmap. This is what makes filtered vector search fast.
Filtered k-NN
The classic Qdrant query is "find the 10 nearest neighbors of v, where category = books and price < 50." The execution plan is: resolve the filter to a candidate set, run HNSW search inside that set, return the top-k.
The HNSW graph traversal is lock-free per point, which lets Qdrant scale concurrent searches without a global mutex.
from qdrant_client import QdrantClient
from qdrant_client.http import models
client = QdrantClient("localhost", port=6333)
hits = client.search(
collection_name="books",
query_vector=embedding,
query_filter=models.Filter(
must=[
models.FieldCondition(key="category", match=models.MatchValue(value="books")),
models.FieldCondition(key="price", range=models.Range(lt=50)),
]
),
limit=10,
with_payload=True,
)
Embedded mode
Since 1.0, Qdrant can run in-process inside a Python or Node application: no separate server, no socket. This is the same Rust binary, just linked directly. You get the same HNSW implementation, the same filter engine, and you save the network round trip per query.
Diagrams
static storyboard — WebGPU animates when available
[caption] Simplified 2-D projection of hierarchical navigable small-world search. Without WebGPU, or when reduced motion is preferred, the static storyboard is shown instead.
A live reenactment of layered HNSW search: sparse amber entry nodes appear first, then the violet mid layer, then the dense teal base layer. The query ring sweeps the space and its nearest neighbours glow.
Result: nodes 10, 22, 16 — the k=4 nearest of the ef=16 beam survivors. This is an *approximate* answer; compare it with exactSearch for recall.
distance evals 9 · visited 7/24 · recall 0.75 vs exact (filtered, k=4, ef=16)
Teaching model: vectors are projected to 2D from a synthetic set so the algorithm's geometry is visible — production embeddings are high-dimensional and this layout is not representative of them. Results are approximate; the exact baseline is computed on the same points for recall.
Qdrant combines HNSW with a payload filter engine: filtered queries prune graph edges whose payload doesnt match, so only valid candidates reach the top-k.
Writes are appended to a WAL and periodically flushed into segment files. Crash recovery replays the WAL into the most recent snapshot.
A query vector enters the HNSW graph; payload filters prune candidates before the top-k selection.
The query combines a vector similarity search with a structured payload filter; the result is a list of (id, score, payload) tuples.
Top layer gives a coarse nearest neighbor; descent into the base layer yields the final top-k.
Example GPU resource values of the kind an index build reports: VRAM use, utilization, power, temperature. These numbers are illustrative — no benchmark was run for this exhibit.
[caption] Illustrative synthetic values, not measurements. vgpu.sh renders this page’s animations; it is not the source of these numbers.
Example GPU resource values of the kind an index build reports: VRAM use, utilization, power, temperature. These numbers are illustrative — no benchmark was run for this exhibit.
A synthetic vectors-per-second series showing the shape an HNSW bulk build might report. The values are illustrative, not measured.
[caption] Synthetic series — no benchmark was run, and no causal story (layer promotions or otherwise) should be read into the dips.
A synthetic vectors-per-second series showing the shape an HNSW bulk build might report. The values are illustrative, not measured.