
Payload Filtering Is Qdrant's Superpower: Go From Docker to Production Vector Search in 15 Minutes
Chris Harper
4 min read
Jul 12, 2026 · 04:13 UTC
Qdrant lets you combine semantic similarity search with exact metadata filters evaluated inside the HNSW index — not after — so filtered queries stay fast even at a billion vectors.
What you'll be able to do after this:
- Spin up a Qdrant instance locally (Docker or in-memory), create a collection, upsert vectors with JSON payloads, and run your first filtered similarity search in Python
- Understand why Qdrant's filterable HNSW avoids the precision-recall tradeoff of post-search filtering at scale
- Compare Qdrant, ChromaDB, and pgvector to know which fits your scale and query pattern
When you need something between a toy in-memory prototype and a Pinecone-scale managed service, Qdrant is the vector database the open-source community keeps reaching for. Written in Rust, it ships as a single Docker image, has a fully managed cloud tier, and crucially: it supports payload filtering evaluated inside the HNSW graph walk — not as a post-search scan.
That's the key differentiator. Most vector search implementations filter after ANN: retrieve the top-100 results, then discard anything that doesn't match category == "sci-fi". At scale, results ranked 101–1000 are discarded unseen — you miss relevant matches. Qdrant's filterable HNSW weaves your filter into the index traversal so you only visit nodes that pass the filter, keeping both precision and recall at scale.
Walk-Through: Filtered Semantic Book Search
1. Start Qdrant (30 seconds)
docker pull qdrant/qdrant
docker run -p 6333:6333 qdrant/qdrant
Skip Docker entirely for local prototyping:
from qdrant_client import QdrantClient
client = QdrantClient(":memory:") # persists nothing; good for dev
2. Install dependencies
pip install qdrant-client sentence-transformers
3. Create a collection
from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams
client = QdrantClient(url="http://localhost:6333")
client.create_collection(
collection_name="books",
vectors_config=VectorParams(size=384, distance=Distance.COSINE),
)
4. Upsert points with payloads
from sentence_transformers import SentenceTransformer
from qdrant_client.models import PointStruct
model = SentenceTransformer("all-MiniLM-L6-v2") # 384-dim, fits the collection above
books = [
{"id": 1, "title": "Dune", "year": 1965, "genre": "sci-fi"},
{"id": 2, "title": "Hyperion", "year": 1989, "genre": "sci-fi"},
{"id": 3, "title": "The Left Hand of Darkness", "year": 1969, "genre": "sci-fi"},
{"id": 4, "title": "Brave New World", "year": 1932, "genre": "dystopian"},
]
client.upsert(
collection_name="books",
points=[
PointStruct(
id=b["id"],
vector=model.encode(b["title"]).tolist(),
payload={"title": b["title"], "year": b["year"], "genre": b["genre"]},
)
for b in books
],
)
5. Filtered similarity search
from qdrant_client.models import Filter, FieldCondition, MatchValue
query_vector = model.encode("desert planet survival story").tolist()
results = client.search(
collection_name="books",
query_vector=query_vector,
query_filter=Filter(
must=[FieldCondition(key="genre", match=MatchValue(value="sci-fi"))]
),
limit=3,
)
for r in results:
print(f"{r.score:.2f} {r.payload['title']}")
# 0.91 Dune
# 0.74 Hyperion
# 0.62 The Left Hand of Darkness
The query_filter is evaluated inside the HNSW graph walk — not after. Brave New World never surfaces because the index walk only visits sci-fi nodes.
Qdrant vs ChromaDB vs pgvector
| Qdrant | ChromaDB | pgvector | |
|---|---|---|---|
| Scale | Billions of vectors | Millions | Millions (Postgres limits) |
| Filtered search | Filter inside HNSW | Post-search scan | Post-search (with index) |
| Deployment | Docker / Cloud | Python in-process | Add-on to Postgres |
| Best for | Production needing filtered search at scale | Local dev / prototyping | Teams already on Postgres |
The resource
Follow the official Semantic Search 101 quickstart on qdrant.tech — it builds a searchable science fiction library in 5 minutes using FastEmbed (no GPU, no SentenceTransformer install needed). The companion YouTube video "Semantic Search for Beginners with Qdrant Vector Database" walks through the same flow visually.
Once you're comfortable with the basics, explore named vectors (multiple embedding models per document in one collection) and sparse-dense hybrid search — Qdrant's production differentiators.
Sources: Semantic Search 101 — Qdrant · Qdrant Local Quickstart · Semantic Search for Beginners — YouTube