You have an embedding model producing 1536-dimensional vectors, a collection of 100,000 documents, and a RAG application that needs to answer in under two seconds. The real challenge is not generating embeddings – it's where to store them and how to query them efficiently. Chroma, Pinecone, and Weaviate are the three most common answers, but they serve very different use cases. Choosing wrong means either overpaying for infrastructure you don't need or hitting a scalability wall. At Meteora Web, we have integrated all three in production systems. This guide gives you the operational criteria to decide, with copy-paste code examples.
The real problem: where do your embeddings live?
Imagine you tokenized a 500-page manual, generated an embedding for each paragraph, and want to perform semantic search. If you store vectors in a Python list and compute cosine similarity for every request, with 10,000 documents you're at ~50 ms, with 500,000 you exceed one second. That doesn't scale. A vector database (or vector search engine) solves this by indexing vectors using structures like HNSW or IVF, enabling approximate nearest neighbor (ANN) search in logarithmic or sublinear time.
Sponsored Protocol
Chroma: simplicity that gets you started in 5 minutes
Chroma is built for developers who want to prototype quickly. It's open source, lightweight, and uses SQLite or DuckDB as a backend. Perfect for personal projects, demos, or applications with up to a few tens of thousands of documents.
Installation and first example
pip install chromadbimport chromadb
from chromadb.utils import embedding_functions
client = chromadb.Client()
collection = client.create_collection("tech_manual")
collection.add(
documents=[
"The server starts in 30 seconds.",
"Network configuration requires a static IP address."
],
ids=["doc1", "doc2"]
)
results = collection.query(query_texts=["how to start the server"], n_results=1)
print(results['documents'][0]) # ['The server starts in 30 seconds.']Note: Chroma includes a default local embedding model, but for production consistency it's better to pass pre-generated embeddings from an external model (e.g., OpenAI text-embedding-ada-002).
Sponsored Protocol
When to use Chroma
Pros: zero configuration, no external server, file-based persistence, ideal for CI/CD and testing. Cons: scalability is limited to process memory; performance degrades beyond ~500K vectors. No hybrid search (vector + lexical) out-of-the-box.
Best for: proof-of-concept, <200K documents, no desire to manage a separate database, tolerant to collection resets.
Pinecone: serverless production without the headache
Pinecone is a fully managed cloud service designed to scale to billions of vectors with <10ms latency. You don't install anything or worry about servers – everything is abstracted behind a REST API. However, it's a paid service, and costs grow linearly with vector count and dimensionality.
Sponsored Protocol
Setup and query
pip install pinecone-clientimport pinecone
pinecone.init(api_key="YOUR_API_KEY", environment="us-west1-gcp")
if "manual" not in pinecone.list_indexes():
pinecone.create_index("manual", dimension=1536, metric="cosine")
index = pinecone.Index("manual")
index.upsert([
("doc1", [0.1]*1536, {"text": "The server starts in 30 seconds."}),
("doc2", [0.2]*1536, {"text": "Network configuration requires a static IP."})
])
query_embedding = [0.15]*1536
result = index.query(query_embedding, top_k=1, include_metadata=True)
print(result['matches'][0]['metadata']['text'])Pros: zero maintenance, automatic horizontal scaling, namespaces for multi-tenancy, native LangChain integration. Cons: vendor lock-in (data only accessible via API), non-trivial cost (~$70+/month for 1M 1536D vectors), limited hybrid search unless using sparse-dense feature.
Best for: >500K vectors, top priority on latency and uptime, no desire to manage infrastructure, budget available.
Weaviate: the open-source Swiss Army knife
Weaviate is an open-source vector database with native hybrid search (vector + lexical), integrated embedding modules (OpenAI, Cohere, Hugging Face), multi-tenancy, and the ability to run on Docker or Kubernetes. It's the most flexible option but requires DevOps skills to run in production.
Launch with Docker and query
docker run -d -p 8080:8080 \
-e AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED=true \
-e PERSISTENCE_DATA_PATH='/var/lib/weaviate' \
semitechnologies/weaviate:latestpip install weaviate-clientimport weaviate
client = weaviate.Client("http://localhost:8080")
class_obj = {
"class": "Document",
"vectorizer": "text2vec-openai",
"moduleConfig": {
"text2vec-openai": {
"model": "ada",
"modelVersion": "002"
}
},
"properties": [
{"name": "text", "dataType": ["text"]}
]
}
client.schema.create_class(class_obj)
client.data_object.create({
"text": "The server starts in 30 seconds."
}, "Document")
# Hybrid query (vector + BM25)
where_filter = {
"path": ["text"],
"operator": "Like",
"valueString": "*starts*"
}
result = client.query.get("Document", ["text"]).with_hybrid(query="server startup", alpha=0.7).with_where(where_filter).do()
print(result['data']['Get']['Document'])Pros: open source, powerful hybrid search, auto-vectorization, native replication and sharding, support for thousands of classes (multi-model). Cons: operational complexity (Docker/K8s, backups, tuning), high resource consumption, steeper learning curve.
Best for: teams with DevOps expertise, desire to avoid lock-in, need for vector + full-text search, volumes up to hundreds of millions of vectors.
Comparison table
| Feature | Chroma | Pinecone | Weaviate |
|---|---|---|---|
| Installation | pip install | API key (cloud) | Docker / K8s |
| Hybrid search | No (vector only) | Yes (sparse-dense) | Yes (BM25 + vector) |
| Scalability | Tens of k vectors | Billions | Hundreds of M |
| Cost (1M vectors 1536D) | $0 (local) | ~$70/month | $0 + server cost |
| Data control | Full (SQLite file) | Vendor | Full (self-hosted) |
| Multi-tenancy | Separate collections | Namespaces | Tenants per class |
| Latency (100k vectors) | ~20ms | ~5ms | ~10ms |
| Integrated AI modules | Local embedding only | No (pass raw vectors) | OpenAI, Cohere, HuggingFace, ... |
Decision criteria: our battle-tested flow
At Meteora Web, we always start with three questions:
- How many vectors do you need to index today – and in 6 months? <200K -> Chroma is fine. Up to 5M -> Weaviate (if you have DevOps) or Pinecone (if you want zero ops). >50M -> Pinecone scales better.
- Do you need hybrid search (keyword + vector)? If yes, Weaviate is the most mature choice. Pinecone has sparse-dense but is less flexible.
- What's your priority between operational cost and latency? Low budget and technical skills -> Weaviate (self-hosted) or Chroma. Production budget and zero stress -> Pinecone.
Typical case: you're building an assistant for a company with 50K technical documents. You don't want to manage servers. In LangChain, you can use PineconeVectorStore in 10 lines. If you must comply with GDPR and data cannot leave on-prem infrastructure, Weaviate on a server inside the data center is the way.
In a nutshell – what to do now
- Install Chroma and test with a 10K document dataset – understand if it fits.
- If latency or scalability becomes a bottleneck, try Pinecone with the free tier (1M vectors).
- If you need hybrid search or want to avoid lock-in, launch Weaviate in Docker and import your data.
- In all cases, don't optimize prematurely: start with the simplest tool and migrate only when you measure the bottleneck.
For deeper integration with LangChain, check our LangChain & LLM Pillar Guide.