Vector databases answer one question: “which stored vectors are closest to this query vector?” General-purpose databases answer it as a feature - an index type bolted onto a relational or document engine. Milvus answers it as the entire product: a distributed system whose storage, compute, and indexing layers all exist to serve approximate nearest-neighbor search at scale. The separation that defines it is storage-compute disaggregation - indexes live on object storage, search nodes are stateless and scaled independently, and writes flow through a log backbone.
Data model
- Collection: the table-equivalent - a schema of fields.
- Fields: scalar columns (ids, categories, timestamps) plus one or more vector fields (dense or sparse embeddings).
- Partition: a logical slice of a collection (for example one per tenant or category), the unit you can load and release independently for query-time isolation.
- Entity: a row - scalar fields plus vector(s).
There is no SQL. Clients are SDKs (Python pymilvus, Java, Go, Node) with a typed filter
expression language for scalar fields, combined with vector parameters per query.
Index types
The index choice is the core tuning decision and is set per vector field:
| Index | Character | Use when |
|---|---|---|
| FLAT | Brute-force exact scan | Small collections, ground-truth baseline |
| IVF_FLAT / IVF_PQ | Inverted-file buckets, PQ adds compression | Medium scale, memory-bounded |
| HNSW | Graph index, high recall, memory-hungry | The default choice for most online workloads |
| DiskANN | Disk-based graph | Large collections that do not fit memory |
| GPU indexes | CUDA-backed builds/search | High-throughput online serving |
| Sparse indexes (SPARSE_INVERTED_INDEX etc.) | Learned-sparse vectors (SPLADE-style) | Hybrid dense+sparse retrieval |
All except FLAT are approximate: you trade recall for latency through index parameters (nprobe,
ef, search_list) at query time.
Consistency levels
Milvus is not a transactional store. Visibility of fresh writes is a consistency level chosen
per collection or per query: Strong, Bounded (staleness bounded by a time window),
Session, or Eventually. Weaker levels let query nodes serve slightly stale snapshots and keep
latency flat while writes stream in. There are no multi-entity ACID transactions - each insert or
delete is atomic per entity, and correctness across entities is the caller’s problem.
Architecture - the part that costs you
A Milvus 2.x cluster is a set of specialized stateless services sharing a log backbone and object storage:
- Proxy: request entry point.
- Query nodes: serve search over loaded segments.
- Data nodes: ingest and compact growing segments.
- Index nodes: build ANN indexes on sealed segments.
- Coord services: metadata, root coordination.
- Dependencies: object storage (MinIO/S3) for segments, etcd for metadata, a message queue (Pulsar or Kafka) as the write-ahead backbone.
This is a genuinely distributed system: real horizontal scale for billions of vectors, and a real operations bill to match - Kubernetes is the expected runtime, and capacity planning means sizing several node pools plus three external dependencies.
Scaling and replication
Read scaling is adding query nodes; write and index throughput scale on their own pools. Data durability rides on object storage. Replication across sites is handled by the surrounding tooling (cluster deployment, backup, and CDC utilities), not by a native multi-region protocol - design DR explicitly.
What actually breaks
- Undersized query memory: an HNSW index over too-large a collection gets loaded partially or swap-thrashes; the symptom is p99 latency collapsing, not an error.
- Index built on the wrong metric: distance metric baked at index time; a cosine workload on a L2 index silently returns wrong rankings.
- Consistency level surprise:
Eventuallyserving a read-your-own-write test looks like lost writes. - Dependency outage: etcd or the message queue down takes the whole cluster with it - they are not optional infrastructure, they are the database.
Where Milvus is the wrong choice
Under a few hundred thousand vectors, a pgvector column inside the PostgreSQL you already run is almost always the better answer - one system, one ops story, transactions included. When you want dedicated vector search without the platform weight, Qdrant covers the middle ground. Milvus earns its keep at genuine billion-scale or when vector search is a first-class service shared across teams - below that, you are running a platform to solve a library problem.
Milvus release support
2 supportedNo published EOL policy. The 2.6 and 3.0 lines both received releases in September 2026; older minor lines are not patched.
| Release | Latest | Released | End of life | Status |
|---|---|---|---|---|
3.0 | 3.0.1 | - | not published | Supported |
2.6 | 2.6.24 | - | not published | Supported |
Data as of 2026-10-01 from github.com. Refresh with node scripts/fetch-versions.mjs.
Where Milvus sits
How this component relates to the rest of the stack. Items without a link are not covered here yet.