Contents

Chapter 1

Indexing Strategy Guide

Choosing the right index type and tuning its parameters is critical for balancing search speed, recall accuracy, and memory usage. This guide covers the two dominant ANN (approximate nearest neighbor) algorithms: HNSW and IVFFlat.

Algorithm Comparison

PropertyHNSWIVFFlat
Search speedVery fastFast
Build speedSlowFast
Memory usageHigh (graph + vectors)Medium (centroids + vectors)
Recall@1095-99%85-95%
Update costLow (incremental)High (re-clustering)
Best forMost workloadsLarge, static datasets

HNSW Parameters

HNSW (Hierarchical Navigable Small World) builds a multi-layer graph where each vector is a node connected to its nearest neighbours.

m (Graph Degree)

Controls how many edges each node has. Higher m means better recall but more memory and slower inserts.

mMemoryRecall@10Insert SpeedBest For
8Low~90%FastLow-memory environments
16Medium~95%MediumGeneral purpose (recommended)
32High~98%SlowHigh-recall requirements
64Very high~99%Very slowResearch / small datasets

ef_construction (Build-Time Search Depth)

Controls the quality of the graph during construction. Higher values produce better graphs but take longer to build.

ef_constructionBuild TimeRecall@10Recommendation
64Fast~92%Quick prototyping
128Medium~95%Good default
200Slow~97%Production (recommended)
400Very slow~99%Maximum quality

ef_search (Query-Time Search Depth)

Controls the depth of search at query time. Can be changed without rebuilding the index.

ef_searchLatencyRecall@10Recommendation
10Very fast~85%Speed-critical applications
50Fast~95%Good default
100Medium~98%Production (recommended)
200Slow~99%Maximum recall

IVFFlat Parameters

IVFFlat (Inverted File with Flat quantization) partitions vectors into Voronoi cells using k-means clustering, then searches only the nearest cells.

lists (Number of Partitions)

Controls how many Voronoi cells the vectors are divided into.

Rule of thumb: lists = sqrt(N) where N is the total number of vectors.

N (vectors)listsnprobeRecall@10
10,00010010~95%
100,00031620~95%
1,000,0001,00050~95%

nprobe (Query-Time Probes)

Controls how many cells are searched at query time. Higher = better recall, slower search.

nprobe / listsRecall@10Speed
1%~70%Very fast
5%~90%Fast
10%~95%Medium (recommended)
20%~98%Slow

Backend-Specific Configuration

Pinecone

Pinecone manages index parameters automatically. Choose between:

  • Serverless: Auto-scaling, pay per query. Best for variable workloads.
  • Pod-based: Dedicated resources. Best for predictable, high-throughput workloads.

Weaviate

Default HNSW config works well. Key overrides:

json
{
  "vectorIndexConfig": {
    "ef": 100,
    "efConstruction": 200,
    "maxConnections": 16,
    "distance": "cosine"
  }
}

ChromaDB

Uses HNSW internally. Key settings:

python
collection = client.create_collection(
    name="my_collection",
    metadata={
        "hnsw:space": "cosine",
        "hnsw:M": 16,
        "hnsw:construction_ef": 200,
        "hnsw:search_ef": 100,
    }
)

pgvector

Supports both HNSW and IVFFlat:

sql
-- HNSW (recommended for most workloads)
CREATE INDEX ON items USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 200);

-- IVFFlat (for very large, static datasets)
CREATE INDEX ON items USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);

-- Set search-time parameters
SET hnsw.ef_search = 100;
SET ivfflat.probes = 10;

Decision Framework

Is your dataset static (rarely updated)?
├── YES
│   ├── Is memory constrained?
│   │   ├── YES → IVFFlat (lists=sqrt(N), nprobe=10%)
│   │   └── NO → HNSW (m=16, ef_construction=200)
│   └──
└── NO (frequent updates)
    └── HNSW (m=16, ef_construction=200)
        IVFFlat requires re-clustering on updates.
Vector Database Toolkit v1.0.0 — Free Preview