Quick Start
This guide covers the most basic use-case: running Qdrant, creating a collection, inserting vectors with payloads, and performing vector search with filtering.
Run Qdrant with Docker
Pull the latest image
Download the latest Qdrant image from DockerHub: docker pull qdrant/qdrant
Run the container
Start Qdrant with default configuration: docker run -p 6333:6333 qdrant/qdrant
This starts an insecure deployment without authentication, open to all network interfaces. For production, refer to secure your instance .
Verify Qdrant is running
Qdrant should now be accessible at http://localhost:6333 . You can check the health status: curl http://localhost:6333/
Production Docker Setup
For a production-ready setup with persistent storage and custom configuration:
docker run -p 6333:6333 -p 6334:6334 \
-v $( pwd ) /qdrant_storage:/qdrant/storage \
-v $( pwd ) /qdrant_snapshots:/qdrant/snapshots \
-v $( pwd ) /config/production.yaml:/qdrant/config/production.yaml \
qdrant/qdrant
Understanding the volume mounts
/qdrant/storage - Where Qdrant persists all your data (mount as volume to prevent data loss)
/qdrant/snapshots - Where Qdrant stores collection snapshots for backup/restore
/qdrant/config/production.yaml - Custom configuration file (override values from the reference config)
For production deployments, set service.api_key in your configuration file to enable authentication.
Create a Collection
Collections are named sets of points (vectors with payloads) that share the same configuration.
Create a collection with 4-dimensional vectors using Dot product metric:
curl -X PUT 'http://localhost:6333/collections/test_collection' \
-H 'Content-Type: application/json' \
--data-raw '{
"vectors": {
"size": 4,
"distance": "Dot"
}
}'
Expected response:
{
"result" : true ,
"status" : "ok" ,
"time" : 0.031095451
}
Verify Collection Creation
Check that your collection was created successfully:
curl 'http://localhost:6333/collections/test_collection'
Expected response:
{
"result" : {
"status" : "green" ,
"vectors_count" : 0 ,
"segments_count" : 5 ,
"disk_data_size" : 0 ,
"ram_data_size" : 0 ,
"config" : {
"params" : {
"vectors" : {
"size" : 4 ,
"distance" : "Dot"
}
},
"hnsw_config" : {
"m" : 16 ,
"ef_construct" : 100 ,
"full_scan_threshold" : 10000
},
"optimizer_config" : {
"deleted_threshold" : 0.2 ,
"vacuum_min_vector_number" : 1000 ,
"default_segment_number" : 2 ,
"max_segment_size" : null ,
"memmap_threshold" : null ,
"indexing_threshold" : 20000 ,
"flush_interval_sec" : 5 ,
"max_optimization_threads" : null
},
"wal_config" : {
"wal_capacity_mb" : 32 ,
"wal_segments_ahead" : 0
}
}
},
"status" : "ok" ,
"time" : 2.1199e-5
}
Note the HNSW configuration with m: 16 (edges per node) and ef_construct: 100 (neighbors during build). These values balance accuracy and performance.
Insert Points
Points consist of a vector, unique ID, and optional payload. Let’s insert 6 points with city information:
curl -L -X PUT 'http://localhost:6333/collections/test_collection/points?wait=true' \
-H 'Content-Type: application/json' \
--data-raw '{
"points": [
{"id": 1, "vector": [0.05, 0.61, 0.76, 0.74], "payload": {"city": "Berlin"}},
{"id": 2, "vector": [0.19, 0.81, 0.75, 0.11], "payload": {"city": ["Berlin", "London"]}},
{"id": 3, "vector": [0.36, 0.55, 0.47, 0.94], "payload": {"city": ["Berlin", "Moscow"]}},
{"id": 4, "vector": [0.18, 0.01, 0.85, 0.80], "payload": {"city": ["London", "Moscow"]}},
{"id": 5, "vector": [0.24, 0.18, 0.22, 0.44], "payload": {"count": [0]}},
{"id": 6, "vector": [0.35, 0.08, 0.11, 0.44]}
]
}'
Expected response:
{
"result" : {
"operation_id" : 0 ,
"status" : "completed"
},
"status" : "ok" ,
"time" : 0.000206061
}
The ?wait=true parameter ensures the operation completes before returning. Without it, the operation is asynchronous.
Understanding Payloads
Point 1 : Simple payload with single city value
Points 2-4 : Array payloads supporting multiple values
Point 5 : Different payload structure (demonstrates flexibility)
Point 6 : No payload (payloads are optional)
Search Vectors
Basic Search
Search for the top 3 most similar vectors:
curl -L -X POST 'http://localhost:6333/collections/test_collection/points/search' \
-H 'Content-Type: application/json' \
--data-raw '{
"vector": [0.2, 0.1, 0.9, 0.7],
"top": 3
}'
Expected response:
{
"result" : [
{ "id" : 4 , "score" : 1.362 , "payload" : null , "version" : 0 },
{ "id" : 1 , "score" : 1.273 , "payload" : null , "version" : 0 },
{ "id" : 3 , "score" : 1.208 , "payload" : null , "version" : 0 }
],
"status" : "ok" ,
"time" : 0.000055785
}
With Dot product distance, higher scores indicate greater similarity. The query completed in ~55 microseconds!
Search with Filtering
Now let’s search for vectors but only from points with “London” in their city payload :
curl -L -X POST 'http://localhost:6333/collections/test_collection/points/search' \
-H 'Content-Type: application/json' \
--data-raw '{
"filter": {
"should": [
{
"key": "city",
"match": {
"value": "London"
}
}
]
},
"vector": [0.2, 0.1, 0.9, 0.7],
"top": 3
}'
Expected response:
{
"result" : [
{ "id" : 4 , "score" : 1.362 },
{ "id" : 2 , "score" : 0.871 }
],
"status" : "ok" ,
"time" : 0.000093972
}
Only points 2 and 4 are returned because they have “London” in their city payload. The filter was applied before similarity search!
Filter Conditions
Qdrant supports powerful filtering with multiple conditions:
Match Value
Range Filter
Combined Conditions
{
"filter" : {
"must" : [
{
"key" : "city" ,
"match" : {
"value" : "Berlin"
}
}
]
}
}
Using Client Libraries
While the examples above use curl, it’s recommended to use official client libraries for production applications.
Python Client
from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams, PointStruct
# Connect to Qdrant
client = QdrantClient( "http://localhost:6333" )
# Create collection
client.create_collection(
collection_name = "test_collection" ,
vectors_config = VectorParams( size = 4 , distance = Distance. DOT ),
)
# Insert points
client.upsert(
collection_name = "test_collection" ,
points = [
PointStruct( id = 1 , vector = [ 0.05 , 0.61 , 0.76 , 0.74 ], payload = { "city" : "Berlin" }),
PointStruct( id = 2 , vector = [ 0.19 , 0.81 , 0.75 , 0.11 ], payload = { "city" : [ "Berlin" , "London" ]}),
# ... more points
],
)
# Search
results = client.search(
collection_name = "test_collection" ,
query_vector = [ 0.2 , 0.1 , 0.9 , 0.7 ],
limit = 3 ,
)
JavaScript/TypeScript Client
import { QdrantClient } from '@qdrant/js-client-rest' ;
const client = new QdrantClient ({ url: 'http://localhost:6333' });
// Create collection
await client . createCollection ( 'test_collection' , {
vectors: { size: 4 , distance: 'Dot' },
});
// Insert points
await client . upsert ( 'test_collection' , {
points: [
{ id: 1 , vector: [ 0.05 , 0.61 , 0.76 , 0.74 ], payload: { city: 'Berlin' } },
{ id: 2 , vector: [ 0.19 , 0.81 , 0.75 , 0.11 ], payload: { city: [ 'Berlin' , 'London' ] } },
// ... more points
],
});
// Search
const results = await client . search ( 'test_collection' , {
vector: [ 0.2 , 0.1 , 0.9 , 0.7 ],
limit: 3 ,
});
Local Development Options
For quick prototyping without Docker:
In-Memory Mode
File-Based Mode
from qdrant_client import QdrantClient
# Creates an in-memory instance (no persistence)
client = QdrantClient( ":memory:" )
In-memory mode is great for testing and CI/CD but data is lost when the process ends.
Next Steps
Installation Guide Explore production deployment options including Kubernetes and cloud
API Documentation Complete REST API reference with all endpoints
Collections Learn about collection configuration, vector types, and indexing
Filtering Master advanced filtering with full-text search, geo-queries, and more
Additional Resources