Vectors are the core data type in Qdrant, representing embeddings generated by machine learning models. Qdrant supports multiple vector types to accommodate different use cases.
Vector Types
Qdrant supports three main vector types:
Dense Vectors
The most common vector type - fixed-size arrays of floating-point numbers:
from qdrant_client import QdrantClient, models
client = QdrantClient( "localhost" , port = 6333 )
# Create collection with dense vectors
client.create_collection(
collection_name = "documents" ,
vectors_config = models.VectorParams(
size = 384 , # Vector dimensionality
distance = models.Distance. COSINE
)
)
# Insert points with dense vectors
client.upsert(
collection_name = "documents" ,
points = [
models.PointStruct(
id = 1 ,
vector = [ 0.05 , 0.61 , 0.76 , 0.74 , ... ], # 384 dimensions
payload = { "text" : "example document" }
)
]
)
// From lib/segment/src/data_types/vectors.rs:253-264
pub type VectorElementType = f32 ;
pub type DenseVector = TypedDenseVector < VectorElementType >;
Dense vectors are ideal for embeddings from models like OpenAI, Cohere, Sentence Transformers, and CLIP.
Sparse Vectors
High-dimensional vectors where most values are zero, stored efficiently:
# Create collection with sparse vectors
client.create_collection(
collection_name = "hybrid_search" ,
vectors_config = models.VectorParams(
size = 384 ,
distance = models.Distance. COSINE
),
sparse_vectors_config = {
"text" : models.SparseVectorParams(
index = models.SparseIndexParams()
)
}
)
# Insert points with sparse vectors
client.upsert(
collection_name = "hybrid_search" ,
points = [
models.PointStruct(
id = 1 ,
vector = {
"dense" : [ 0.1 , 0.2 , 0.3 , ... ],
"text" : models.SparseVector(
indices = [ 10 , 45 , 98 , 234 , 567 ], # Non-zero dimensions
values = [ 0.5 , 0.3 , 0.8 , 0.2 , 0.4 ] # Corresponding values
)
},
payload = { "text" : "sparse vector example" }
)
]
)
Sparse vectors are perfect for:
BM25-style keyword search
TF-IDF representations
SPLADE embeddings
Hybrid dense + sparse search
Multi-Vectors (ColBERT-style)
Multiple dense vectors per point, useful for token-level embeddings:
# Create collection with multi-vector support
client.create_collection(
collection_name = "colbert_search" ,
vectors_config = {
"text" : models.VectorParams(
size = 128 ,
distance = models.Distance. COSINE ,
multivector_config = models.MultiVectorConfig(
comparator = models.MultiVectorComparator. MAX_SIM
)
)
}
)
# Insert points with multiple vectors
client.upsert(
collection_name = "colbert_search" ,
points = [
models.PointStruct(
id = 1 ,
vector = {
"text" : [
[ 0.1 , 0.2 , ... ], # Token 1 embedding
[ 0.3 , 0.4 , ... ], # Token 2 embedding
[ 0.5 , 0.6 , ... ] # Token 3 embedding
]
},
payload = { "text" : "multi-vector example" }
)
]
)
// From lib/segment/src/types.rs:1542-1546
pub struct MultiVectorConfig {
/// How to compare multivector points
pub comparator : MultiVectorComparator ,
}
Multi-vectors enable ColBERT-style search where documents are split into multiple token embeddings for fine-grained matching.
Named Vectors
Store multiple vector types in the same point for multimodal search:
# Create collection with named vectors
client.create_collection(
collection_name = "multimodal" ,
vectors_config = {
"image" : models.VectorParams(
size = 512 ,
distance = models.Distance. COSINE
),
"text" : models.VectorParams(
size = 384 ,
distance = models.Distance. COSINE
),
"audio" : models.VectorParams(
size = 256 ,
distance = models.Distance. DOT
)
}
)
# Insert multimodal points
client.upsert(
collection_name = "multimodal" ,
points = [
models.PointStruct(
id = 1 ,
vector = {
"image" : [ 0.1 , 0.2 , ... ], # 512-dim CLIP image embedding
"text" : [ 0.3 , 0.4 , ... ], # 384-dim text embedding
"audio" : [ 0.5 , 0.6 , ... ] # 256-dim audio embedding
},
payload = {
"title" : "Multimodal content" ,
"type" : "video"
}
)
]
)
# Search using specific vector
results = client.search(
collection_name = "multimodal" ,
query_vector = ( "image" , [ 0.1 , 0.2 , ... ]),
limit = 10
)
// From lib/segment/src/data_types/vectors.rs:259-260
pub const DEFAULT_VECTOR_NAME : & VectorName = "" ;
Named vectors are ideal for:
Cross-modal search (text-to-image, image-to-text)
Multimodal retrieval
Multiple embedding models per document
A/B testing different embeddings
Vector Storage Configuration
Control how vectors are stored for optimal performance:
client.create_collection(
collection_name = "optimized" ,
vectors_config = models.VectorParams(
size = 768 ,
distance = models.Distance. COSINE ,
on_disk = False # Store in RAM for best performance
)
)
// From lib/segment/src/types.rs:1492-1513
pub enum VectorStorageType {
Memory , // In RAM - fastest
Mmap , // Memory-mapped file
ChunkedMmap , // Chunked memory-mapped, appendable
InRamChunkedMmap , // Locked in RAM, no disk access
InRamMmap , // Pre-fetched into RAM on load
}
Fastest option. All vectors stored in RAM. Best for:
Small to medium datasets (< available RAM)
Maximum query performance
Real-time applications
Balanced option. OS manages memory/disk swapping. Best for:
Large datasets (> available RAM)
Cost-effective deployments
Acceptable query latency
Appendable memory-mapped storage. Best for:
Growing collections
Continuous ingestion
Disk-based storage with good performance
Vector Datatype Configuration
Qdrant supports different storage precision levels:
client.create_collection(
collection_name = "compressed" ,
vectors_config = models.VectorParams(
size = 768 ,
distance = models.Distance. COSINE ,
datatype = models.Datatype. FLOAT16 # Half precision
)
)
// From lib/segment/src/types.rs:1528-1536
pub enum VectorStorageDatatype {
Float32 , // Single-precision (default)
Float16 , // Half-precision
Uint8 , // Unsigned 8-bit integer
}
Datatype Memory Precision Use Case Float32 4 bytes/dim Full Default, best accuracy Float16 2 bytes/dim Half 50% memory savings, minimal accuracy loss Uint8 1 byte/dim Low 75% memory savings, requires quantization
Reducing datatype precision saves memory but may reduce search quality. Always benchmark with your data.
Vector Dimensions
Common embedding model dimensions:
Model Dimensions Distance OpenAI text-embedding-3-small 1536 Cosine OpenAI text-embedding-3-large 3072 Cosine Cohere embed-english-v3.0 1024 Cosine Sentence Transformers (all-MiniLM-L6-v2) 384 Cosine CLIP ViT-B/32 512 Cosine BGE-large-en-v1.5 1024 Cosine
Vector dimensions must match your embedding model exactly. Qdrant validates this during insertion.
Sparse Vector Configuration
Configure sparse vector indexing:
client.create_collection(
collection_name = "sparse_collection" ,
sparse_vectors_config = {
"bm25" : models.SparseVectorParams(
index = models.SparseIndexParams(
full_scan_threshold = 10000 ,
on_disk = False
)
)
}
)
// From lib/segment/src/types.rs:1681-1697
pub struct SparseVectorDataConfig {
pub index : SparseIndexConfig ,
pub storage_type : SparseVectorStorageType ,
pub modifier : Option < Modifier >,
}
Sparse vectors automatically use an inverted index structure optimized for high-dimensional sparse data.
Multi-Vector Comparators
Control how multi-vectors are compared:
// From lib/segment/src/types.rs:1562-1565
pub enum MultiVectorComparator {
MaxSim , // Maximum similarity across all vectors
}
MaxSim : Computes similarity between each query vector and each document vector, returns the maximum. This is the ColBERT approach.
Vector Preprocessing
Normalization
For Cosine distance, normalize vectors:
import numpy as np
def normalize_vector ( vector ):
"""Normalize vector to unit length"""
norm = np.linalg.norm(vector)
if norm == 0 :
return vector
return vector / norm
vector = [ 0.1 , 0.2 , 0.3 ]
normalized = normalize_vector(vector)
client.upsert(
collection_name = "my_collection" ,
points = [
models.PointStruct(
id = 1 ,
vector = normalized.tolist(),
payload = { "text" : "example" }
)
]
)
Some embedding models return pre-normalized vectors. Check your model’s documentation before normalizing.
Best Practices
Match your embedding model
Always use the same vector dimensions, distance metric, and normalization as your embedding model was trained with.
Use sparse vectors for hybrid search
Combine dense semantic vectors with sparse keyword vectors for best retrieval quality.
Consider multi-vectors for long documents
For documents longer than your model’s context window, use multi-vectors to preserve fine-grained information.
Optimize storage for scale
For large collections, use Float16 datatype and on-disk storage to reduce memory usage.
Use named vectors for multimodal
When working with multiple data types (text, images, audio), use named vectors to keep embeddings organized.
Collections Learn how collections configure vector storage
Points Understand how vectors are stored in points
Distance Metrics Deep dive into distance metrics for vector comparison
Indexing Explore how vectors are indexed for fast search