Zvec Index Types: Supported Indexes and Performance Trade-offs in Alibaba Zvec
Zvec supports four index types—Flat (exact), IVF (inverted file), HNSW (graph-based), and Invert (scalar)—each offering distinct trade-offs between query latency, memory overhead, and recall accuracy.
The alibaba/zvec repository provides a high-performance vector database engine with pluggable indexing strategies. Understanding the available zvec index types and their implementation details is essential for optimizing search performance across different data scales and accuracy requirements.
Supported Zvec Index Types
Flat Index (Exact Search)
The Flat index performs a brute-force scan of all vectors without building auxiliary data structures. Defined in src/include/zvec/core/interface/index_param.h (lines 56-64), this index type stores raw vectors sequentially and computes exact distances during query time.
Use Flat indexes when your dataset fits in memory and you require 100% recall. The trade-off is linear query complexity O(N·D), making it unsuitable for large collections.
IVF Index (Inverted File)
The IVF (Inverted File) index implements a two-level quantization strategy. As defined in src/include/zvec/db/type.h (lines 23-29), IVF partitions the vector space into nlist coarse cells using a quantizer. Each cell maintains an inverted list of vector IDs belonging to that partition.
Query performance depends on the nprobe parameter—the number of cells to probe during search. Higher nprobe values improve recall at the cost of increased latency. IVF offers a balanced speed-vs-accuracy trade-off for medium-to-large static collections.
HNSW Index (Hierarchical Navigable Small World)
The HNSW index constructs a multi-layer proximity graph for approximate nearest neighbor (ANN) search. Also defined in src/include/zvec/db/type.h, HNSW provides logarithmic query complexity with parameters M (graph connectivity), ef_construction (build-time quality), and ef_search (query-time quality).
HNSW excels at large-scale, high-recall workloads and supports dynamic inserts and deletes without full index rebuilds. Memory overhead is moderate—typically 2-4× the raw vector size due to graph edge storage.
Invert Index (Scalar Fields)
The INVERT index handles non-vector data types (strings, numbers, arrays) for the SQL query engine. Defined alongside IVF and HNSW in src/include/zvec/db/type.h, this index enables exact-match filtering and join operations on scalar columns.
Invert indexes are essential for hybrid queries that combine vector similarity search with structured predicates.
Performance Trade-offs and Selection Guide
| Index | Build Cost | Memory Overhead | Query Latency | Recall | Update Support |
|---|---|---|---|---|---|
| Flat | O(N·D) – stores raw vectors only | Minimal (raw vectors) | Linear O(N·D) | 100% (exact) | Trivial append-only |
| IVF | O(N·D) for quantizer training + assignment | ~0.5-1× raw size (centroids + lists) | Sub-linear (nprobe × avg list size) | Tunable via nprobe | Rebuild or incremental add |
| HNSW | Higher (graph construction with M, ef_construction) | ~2-4× raw size (graph edges) | Logarithmic O(log N) with ef_search | >95% typical; tunable via ef_search | Fully dynamic (add/remove) |
| INVERT | Negligible (hash/bitmap) | Depends on cardinality; usually << vector storage | O(1) exact match | Exact (deterministic) | Efficient insert/delete |
When to Choose Each Index
- Flat: Use for small collections (<100k vectors) or when exact results are mandatory.
- IVF: Select for medium-to-large static datasets where you need configurable recall without the memory overhead of graph structures.
- HNSW: Choose for large-scale, high-throughput ANN workloads requiring dynamic updates and sub-millisecond latency.
- INVERT: Deploy for SQL filtering on metadata fields, typically in conjunction with vector indexes for hybrid search.
Implementation Details and Key Files
The IndexType enum in src/include/zvec/core/interface/index_param.h defines the vector index types (kFlat, kIVF, kHNSW) available to the IndexFactory. The broader IndexType enum in src/include/zvec/db/type.h extends this set to include INVERT for scalar fields.
IndexFactory::CreateAndInitIndex (implemented in src/core/interface/index_factory.cc, lines 41-48) instantiates the concrete implementations: FlatIndex, IVFIndex, and HNSWIndex. These classes inherit from the abstract Index interface defined in src/include/zvec/core/interface/index.h.
Parameter structures for each index type reside in src/include/zvec/db/index_params.h, while the Python bindings in python/zvec/zvec.py expose these configurations via JSON serialization.
Code Examples
Flat Index (C++)
#include <zvec/core/interface/index_factory.h>
#include <zvec/core/interface/index_param_builders.h>
using namespace zvec::core_interface;
auto flat_param = FlatIndexParamBuilder()
.WithVersion(1)
.WithIndexType(IndexType::kFlat)
.WithMetricType(MetricType::kInnerProduct)
.WithDimension(128)
.Build();
auto flat_idx = IndexFactory::CreateAndInitIndex(*flat_param);
IVF Index (C++)
auto ivf_param = IVFIndexParamBuilder()
.WithVersion(1)
.WithIndexType(IndexType::kIVF)
.WithMetricType(MetricType::kCosine)
.WithDimension(128)
.WithNList(1024) // coarse centroids
.Build();
auto ivf_idx = IndexFactory::CreateAndInitIndex(*ivf_param);
// Query-time parameter
IVFQueryParam query;
query.nprobe = 16; // cells to probe
HNSW Index (C++)
auto hnsw_param = HNSWIndexParamBuilder()
.WithVersion(1)
.WithIndexType(IndexType::kHNSW)
.WithMetricType(MetricType::kL2) // Euclidean
.WithDimension(128)
.WithM(16) // graph connectivity
.WithEFConstruction(200) // build quality
.Build();
auto hnsw_idx = IndexFactory::CreateAndInitIndex(*hnsw_param);
// Search parameter
HNSWQueryParam qp;
qp.ef_search = 100; // higher = better recall, slower
Inverted Index (C++)
auto invert_param = IndexParams(IndexType::INVERT); // scalar index
auto invert_idx = IndexFactory::CreateAndInitIndex(invert_param);
Python Configuration (JSON)
import zvec
json_str = """
{
"index_type": "kIVF",
"metric_type": "kCosine",
"dimension": 128,
"nlist": 1024
}
"""
param = zvec.IndexParam.from_json(json_str)
index = zvec.IndexFactory.create_and_init(param)
Summary
- Zvec index types include Flat (exact brute-force), IVF (inverted file with coarse quantization), HNSW (proximity graph for ANN), and INVERT (scalar field indexing).
- Flat guarantees 100% recall with linear scan latency; choose it for small datasets or exact requirements.
- IVF offers tunable speed-vs-recall via
nlistandnprobeparameters; ideal for medium-scale static collections. - HNSW provides logarithmic query complexity and dynamic updates via graph parameters
M,ef_construction, andef_search; best for large-scale, high-throughput ANN workloads. - INVERT handles non-vector data for SQL filtering and hybrid search scenarios.
- Implementation resides in
src/include/zvec/core/interface/index_param.h,src/include/zvec/db/type.h, andsrc/core/interface/index_factory.cc.
Frequently Asked Questions
What is the difference between Flat and HNSW indexes in zvec?
Flat performs an exhaustive brute-force scan of all vectors, guaranteeing exact results (100% recall) but with O(N·D) query complexity. HNSW constructs a multi-layer proximity graph that enables approximate nearest neighbor search with O(log N) complexity, trading a small accuracy margin (typically >95% recall) for orders-of-magnitude faster queries on large datasets.
When should I use IVF instead of HNSW for vector search?
Choose IVF when you have medium-to-large static collections where you need a configurable balance between build cost and query performance without the memory overhead of graph structures. IVF is often preferred when you can tolerate occasional index rebuilds and want to tune recall via the nprobe parameter. Select HNSW when you require dynamic updates without rebuilding, or when you need the lowest possible latency on billion-scale datasets.
Does zvec support dynamic updates to HNSW indexes?
Yes, according to the implementation in src/include/zvec/core/interface/index.h and src/core/interface/index_factory.cc, HNSW indexes support fully dynamic operations. You can add or remove vectors without triggering a full index rebuild, making HNSW suitable for online serving scenarios with frequent data changes. This contrasts with IVF indexes, which typically require re-assignment to centroids or partial rebuilds for optimal performance after significant updates.
How do I configure the nprobe parameter for IVF indexes in zvec?
The nprobe parameter controls the number of inverted lists to scan during query execution. In C++, set it via the IVFQueryParam structure after building the index:
IVFQueryParam query;
query.nprobe = 16; // Trade-off: higher values improve recall but increase latency
Higher nprobe values improve recall by examining more candidate cells but linearly increase query time. For most applications, start with nprobe set to 5-10% of your nlist value and tune based on your specific recall requirements.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →