> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/qdrant/qdrant/llms.txt
> Use this file to discover all available pages before exploring further.

# Vectors

> Understanding vector types in Qdrant - dense, sparse, and multi-vectors for semantic search

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:

```python theme={null}
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"}
        )
    ]
)
```

```rust theme={null}
// From lib/segment/src/data_types/vectors.rs:253-264
pub type VectorElementType = f32;
pub type DenseVector = TypedDenseVector<VectorElementType>;
```

<Info>
  Dense vectors are ideal for embeddings from models like OpenAI, Cohere, Sentence Transformers, and CLIP.
</Info>

### Sparse Vectors

High-dimensional vectors where most values are zero, stored efficiently:

```python theme={null}
# 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"}
        )
    ]
)
```

<Tip>
  Sparse vectors are perfect for:

  * BM25-style keyword search
  * TF-IDF representations
  * SPLADE embeddings
  * Hybrid dense + sparse search
</Tip>

### Multi-Vectors (ColBERT-style)

Multiple dense vectors per point, useful for token-level embeddings:

```python theme={null}
# 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"}
        )
    ]
)
```

```rust theme={null}
// From lib/segment/src/types.rs:1542-1546
pub struct MultiVectorConfig {
    /// How to compare multivector points
    pub comparator: MultiVectorComparator,
}
```

<Info>
  Multi-vectors enable ColBERT-style search where documents are split into multiple token embeddings for fine-grained matching.
</Info>

## Named Vectors

Store multiple vector types in the same point for multimodal search:

```python theme={null}
# 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
)
```

```rust theme={null}
// From lib/segment/src/data_types/vectors.rs:259-260
pub const DEFAULT_VECTOR_NAME: &VectorName = "";
```

<Tip>
  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
</Tip>

## Vector Storage Configuration

Control how vectors are stored for optimal performance:

```python theme={null}
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
    )
)
```

```rust theme={null}
// 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
}
```

<Accordion title="Memory (RAM)">
  **Fastest** option. All vectors stored in RAM. Best for:

  * Small to medium datasets (\< available RAM)
  * Maximum query performance
  * Real-time applications
</Accordion>

<Accordion title="Mmap (Memory-mapped)">
  **Balanced** option. OS manages memory/disk swapping. Best for:

  * Large datasets (> available RAM)
  * Cost-effective deployments
  * Acceptable query latency
</Accordion>

<Accordion title="ChunkedMmap">
  **Appendable** memory-mapped storage. Best for:

  * Growing collections
  * Continuous ingestion
  * Disk-based storage with good performance
</Accordion>

## Vector Datatype Configuration

Qdrant supports different storage precision levels:

```python theme={null}
client.create_collection(
    collection_name="compressed",
    vectors_config=models.VectorParams(
        size=768,
        distance=models.Distance.COSINE,
        datatype=models.Datatype.FLOAT16  # Half precision
    )
)
```

```rust theme={null}
// 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 |

<Warning>
  Reducing datatype precision saves memory but may reduce search quality. Always benchmark with your data.
</Warning>

## 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   |

<Info>
  Vector dimensions must match your embedding model exactly. Qdrant validates this during insertion.
</Info>

## Sparse Vector Configuration

Configure sparse vector indexing:

```python theme={null}
client.create_collection(
    collection_name="sparse_collection",
    sparse_vectors_config={
        "bm25": models.SparseVectorParams(
            index=models.SparseIndexParams(
                full_scan_threshold=10000,
                on_disk=False
            )
        )
    }
)
```

```rust theme={null}
// From lib/segment/src/types.rs:1681-1697
pub struct SparseVectorDataConfig {
    pub index: SparseIndexConfig,
    pub storage_type: SparseVectorStorageType,
    pub modifier: Option<Modifier>,
}
```

<Tip>
  Sparse vectors automatically use an inverted index structure optimized for high-dimensional sparse data.
</Tip>

## Multi-Vector Comparators

Control how multi-vectors are compared:

```rust theme={null}
// 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:

```python theme={null}
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"}
        )
    ]
)
```

<Warning>
  Some embedding models return pre-normalized vectors. Check your model's documentation before normalizing.
</Warning>

## Best Practices

<Accordion title="Match your embedding model">
  Always use the same vector dimensions, distance metric, and normalization as your embedding model was trained with.
</Accordion>

<Accordion title="Use sparse vectors for hybrid search">
  Combine dense semantic vectors with sparse keyword vectors for best retrieval quality.
</Accordion>

<Accordion title="Consider multi-vectors for long documents">
  For documents longer than your model's context window, use multi-vectors to preserve fine-grained information.
</Accordion>

<Accordion title="Optimize storage for scale">
  For large collections, use Float16 datatype and on-disk storage to reduce memory usage.
</Accordion>

<Accordion title="Use named vectors for multimodal">
  When working with multiple data types (text, images, audio), use named vectors to keep embeddings organized.
</Accordion>

## Related Concepts

<CardGroup cols={2}>
  <Card title="Collections" icon="layer-group" href="/concepts/collections">
    Learn how collections configure vector storage
  </Card>

  <Card title="Points" icon="circle-dot" href="/concepts/points">
    Understand how vectors are stored in points
  </Card>

  <Card title="Distance Metrics" icon="ruler" href="/concepts/distance-metrics">
    Deep dive into distance metrics for vector comparison
  </Card>

  <Card title="Indexing" icon="magnifying-glass" href="/concepts/indexing">
    Explore how vectors are indexed for fast search
  </Card>
</CardGroup>
