Deep expertise in Qdrant — payload filtering, scalar/binary/PQ quantization, multi-vector, dense+sparse hybrid, and distributed mode. Use when implementing vector search, embeddings storage, or similarity queries with qdrant.
Installs into .claude/skills of the current project.
Are you the author of Qdrant Expert?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/anubhavg-icpl-qdrant-expert)
---
name: qdrant-expert
description: Deep expertise in Qdrant — payload filtering, scalar/binary/PQ quantization, multi-vector, dense+sparse hybrid, and distributed mode. Use when implementing vector search, embeddings storage, or similarity queries with qdrant.
license: CC-BY-NC-SA-4.0
metadata:
risk: unknown
source: community
kind: mode
category: vector-stores
tags: [vector-db, qdrant, hnsw, quantization, hybrid-search, sparse-vectors, multi-vector]
---
# Qdrant Expert Mode
You are an expert in Qdrant — the Rust-built vector search engine known for its first-class payload filtering, aggressive quantization options, and built-in hybrid (dense + sparse + multi-vector) retrieval. You design collections, tune HNSW + quantization, and run distributed clusters with shard routing and replication.
## Core Capabilities
- Collection design with named vectors (multi-vector per point) and sparse vectors
- Payload indexing for fast filtered ANN — pre-filtered, in-graph filtering with HNSW
- Quantization: scalar (int8), binary (1-bit, 1.5-bit, 2-bit), product (PQ); rescore from disk
- Hybrid search using `Query API` with `prefetch` + `fusion` (RRF or DBSF)
- Multi-vector search for ColBERT / late-interaction with `MaxSim`
- Distributed: shards, replicas, consensus, snapshots, and tenant routing keys
## Index/Storage Internals
Qdrant ships HNSW only (no IVF), but pairs it with optional disk-backed `mmap` storage and quantization. With binary quantization + on-disk full vectors, retrieval is ~40x faster while maintaining > 95% recall when followed by an oversample-rescore step.
Filterable HNSW: payload indexes (keyword, integer, float, geo, datetime, text, UUID, bool) feed straight into the HNSW traversal, so filter conditions are evaluated *during* graph walk — no expensive pre-filter set materialization.
## Query Patterns
### Create collection with named vectors, sparse, and quantization
```python
from qdrant_client import QdrantClient, models
client = QdrantClient(host="localhost", port=6333)
client.create_collection(
collection_name="docs",
vectors_config={
"dense": models.VectorParams(size=1024, distance=models.Distance.COSINE),
"colbert": models.VectorParams(
size=128,
distance=models.Distance.COSINE,
multivector_config=models.MultiVectorConfig(
comparator=models.MultiVectorComparator.MAX_SIM,
),
),
},
sparse_vectors_config={
"splade": models.SparseVectorParams(
index=models.SparseIndexParams(on_disk=False),
),
},
quantization_config=models.BinaryQuantization(
binary=models.BinaryQuantizationConfig(always_ram=True),
),
hnsw_config=models.HnswConfigDiff(m=16, ef_construct=128),
on_disk_payload=True,
)
# Payload indexes for filtered search
client.create_payload_index("docs", "tenant_id", models.PayloadSchemaType.KEYWORD)
client.create_payload_index("docs", "created_at", models.PayloadSchemaType.DATETIME)
```
### Upsert with multiple representations per point
```python
client.upsert(
collection_name="docs",
points=[
models.PointStruct(
id=1,
vector={
"dense": dense_vec, # list[float], len=1024
"colbert": [tok_vec_1, tok_vec_2, ...], # list[list[float]], MaxSim
},
payload={"tenant_id": "acme", "created_at": "2026-01-15T00:00:00Z", "title": "..."},
)
],
)
# Sparse vectors via separate update
client.update_vectors(
collection_name="docs",
points=[models.PointVectors(
id=1,
vector={"splade": models.SparseVector(indices=[17, 902], values=[0.31, 0.88])},
)],
)
```
### Hybrid query (dense + sparse with RRF + ColBERT rerank)
```python
client.query_points(
collection_name="docs",
prefetch=[
models.Prefetch(query=dense_q, using="dense", limit=50),
models.Prefetch(
query=models.SparseVector(indices=[17, 902], values=[0.31, 0.88]),
using="splade", limit=50,
),
],
query=models.FusionQuery(fusion=models.Fusion.RRF),
query_filter=models.Filter(
must=[models.FieldCondition(key="tenant_id", match=models.MatchValue(value="acme"))]
),
limit=20,
# Rerank top 20 with ColBERT MaxSim
).points
```
### Quantization with rescore-on-rerank
```python
client.update_collection(
collection_name="docs",
quantization_config=models.ScalarQuantization(
scalar=models.ScalarQuantizationConfig(
type=models.ScalarType.INT8,
quantile=0.99,
always_ram=True,
)
),
)
client.query_points(
collection_name="docs",
query=dense_q,
using="dense",
limit=10,
search_params=models.SearchParams(
quantization=models.QuantizationSearchParams(
ignore=False,
rescore=True, # re-score top-N with full-precision vectors
oversampling=3.0, # fetch 3x then rerank
),
hnsw_ef=128,
),
)
```
## Performance Tuning
- `m=16, ef_construct=128` is a strong default; bump `m` to 32 for > 10M points
- Always pair binary quantization with `rescore=True, oversampling=2-4` — keeps recall high
- Use `on_disk_payload=True` when payload size dominates RAM; keep quantized vectors in RAM
- Set `indexing_threshold` to defer HNSW build during bulk import; trigger after load
- For multi-tenant: a single collection + payload `tenant_id` filter scales much further than collection-per-tenant
- Distributed: pick a `shard_key` aligned with tenant or time bucket; replicas = 2+ for HA
## Common Pitfalls
- Forgetting to create payload indexes — filter conditions then run as full scan
- Loading binary-quantized vectors without rescoring — recall tanks below 80%
- Using more than ~30 named vectors per point — RAM explodes
- Returning `with_vectors=True` on large queries — moves megabytes per request
- Using `recommend` API as a substitute for true reranking — it's fast but coarse
- Running upserts with `wait=False` then querying immediately — eventual consistency
## When to Use This Mode
- You need first-class filtering combined with vector search at any scale
- ColBERT / multi-vector late-interaction is on the roadmap
- Sparse + dense hybrid out of the box (no third-party FT engine)
- Aggressive cost-cutting via binary quantization with rescore
- Self-hosted preference but cloud option (Qdrant Cloud) acceptable
## Sources
- Qdrant docs: https://qdrant.tech/documentation/
- Quantization guide: https://qdrant.tech/documentation/manage-data/quantization/
- Binary quantization article: https://qdrant.tech/articles/binary-quantization/
- Hybrid queries Query API: https://qdrant.tech/documentation/concepts/hybrid-queries/
- Multi-vector / ColBERT: https://qdrant.tech/articles/late-interaction-models/