Chroma vs Milvus

Both are catalogued under Vector & Storage. The figures come from the GitHub API; the assessments are ours.

At a glance

At a glanceChromaMilvus
LicenseApache-2.0Apache-2.0
LanguagesRust, PythonGo, C++
DeploymentRuns locally / Self-hosted / Managed cloudSelf-hosted / Managed cloud
MaturityEstablishedEstablished
Stars29.1k45.6k
Star growth over the last 7 days−2 ★+1 ★
Forks2.4k4.2k
Open issues7931.3k
Last commit15 Aug 202615 Aug 2026
ActivityActiveActive

What each one does

Chroma

The lowest-friction way to get retrieval working: no server to stand up, no cluster to size. That makes it excellent for prototypes and small production loads, and the point at which you outgrow it is a real consideration to plan for rather than discover.

Full entry →

Milvus

Separates storage from compute so indexing and querying scale independently — the architecture you want at billions of vectors. That capability comes with operational weight; below a few million vectors, something simpler will serve you better.

Full entry →

What you can do

Chroma

  • Get retrieval running in one filechromadb.Client() creates an in-memory store and collection.add() handles tokenization, embedding and indexing, so no embedding model is wired up by hand.
  • Filter alongside the vector searchcollection.query() takes where for metadata equality and where_document with $contains for substring matching in the same call as the similarity search.
  • Move to client-server modechroma run --path /chroma_db_path starts a server against the same four-function API once a single embedded process is no longer enough.
  • Query from Python or JavaScriptThe Python client comes from pip install chromadb and the JavaScript one from npm install chromadb; pointed at the same chroma run server, both work on one set of collections, so the job that writes and the service that queries need not share a language.

Milvus

  • Prototype without running a serverpymilvus[milvus-lite] lets MilvusClient persist to a local file, and the same client code reaches a self-hosted cluster or Zilliz Cloud by swapping uri and token.
  • Mix full-text and vector searchSparse and dense vectors sit in one collection, so BM25 full-text search and learned sparse embeddings such as SPLADE and BGE-M3 can be fused with dense results through a rerank function.
  • Choose an index per workloadHNSW, IVF, FLAT, SCANN and DiskANN are all available, along with quantization variants such as IVFPQ, mmap for memory pressure, and GPU indexing via NVIDIA CAGRA.
  • Scale reads and writes separatelyThe distributed architecture splits compute from storage, so read-heavy traffic is served by adding query nodes and write-heavy ingestion by adding data nodes, with replicas for fault tolerance.
  • Isolate tenants in one clusterIsolation can be set at database, collection, partition or partition-key level, combined with RBAC, TLS and hot/cold storage tiers to keep frequently accessed data in memory or on SSD.

Other comparisons