Module 1: Why Vector Databases for AI Engineers
When you DO need a vector database
Capsule overview
You've seen the limitations of SQL, NoSQL, and numpy. Now the critical question: When DO you need a vector database?
This capsule gives you clear, quantitative criteria to decide. It's not "always use a vector DB" or "never use numpy." It's: "IF you meet these 4 criteria, a vector DB is necessary. If not, alternatives may be enough."
By the end of this capsule, you'll be able to evaluate your RAG project in 5 minutes and decide whether you need a vector DB or not.
The 4 decision criteria
Criterion 1: Scale (# of vectors)
Simple rule:
<1K vectors: numpy enough (prototype)
1K-10K vectors: numpy acceptable (development)
10K-100K: gray zone (evaluate latency)
>100K vectors: vector DB needed (production)
Why 100K is the inflection point:
- numpy with 100K: ~150ms latency (acceptable limit)
- numpy with 500K: ~750ms latency (unusable for RAG)
- ChromaDB with 100K: ~8ms (excellent)
- ChromaDB with 500K: ~12ms (excellent)
Quick calculation:
# Estimate the # of vectors in your project
docs = 50_000 # documents
chunks_per_doc = 3 # average chunks per doc
total_vectors = docs * chunks_per_doc
print(f"Total vectors: {total_vectors:,}")
# Output: Total vectors: 150,000
# Decision:
if total_vectors > 100_000:
print("→ Vector DB needed")
else:
print("→ numpy may be enough (evaluate latency)")
Criterion 2: Latency (<500ms retrieval)
Simple rule:
Latency requirement | Option
----------------------|-------------------
No requirement | numpy (batch processing)
<5s | numpy/SQL can work
<1s | Gray zone (evaluate)
<500ms | Vector DB needed
<100ms | Vector DB mandatory
Why <500ms is critical:
Total RAG latency:
Query embedding: 200ms (OpenAI API)
Retrieval: ???ms (search over vectors)
Generation: 2,500ms (GPT-4)
-----------------------------------
Total: 2,700ms + retrieval
To meet <3s total:
- Retrieval must be: 3000ms - 2700ms = <300ms
- Ideally <100ms (buffer for variability)
Benchmark your setup:
import numpy as np
import time
# Your current database
embeddings = np.load('your_embeddings.npy') # Shape: (n_vectors, 1536)
query = np.random.randn(1536)
# Measure latency
start = time.time()
similarities = np.dot(embeddings, query)
top_5 = np.argsort(similarities)[-5:][::-1]
latency_ms = (time.time() - start) * 1000
print(f"Retrieval latency: {latency_ms:.1f}ms")
# Decision:
if latency_ms > 500:
print("→ Vector DB needed (numpy too slow)")
elif latency_ms > 100:
print("→ Gray zone (vector DB recommended if it will grow)")
else:
print("→ numpy enough (for now)")
Criterion 3: Persistence (durable storage)
Simple rule:
Deployment type | Persistence | Option
----------------------|--------------|------------------
Jupyter notebook | Not critical | numpy in memory
One-off script | Not critical | numpy + .npy save
Service with uptime | Critical | Vector DB needed
Production API | Critical | Vector DB mandatory
Why persistence matters:
Without robust persistence (numpy):
- Restart/crash = data loss OR 30-60s reload
- Deployment = 30-60s downtime (reload embeddings)
- Corruption risk (process interrupted during
.save())
With persistence (Vector DB):
- Restart/crash = <1ms reconnection (index persists)
- Deployment = zero downtime (index already on disk)
- ACID transactions (no corruption)
Evaluation:
Does your service need 99%+ uptime?
├─ YES → Vector DB needed
└─ NO → numpy can work
Can you tolerate 30-60s downtime on every deploy?
├─ YES → numpy can work
└─ NO → Vector DB needed
Do you have >10K vectors that take hours to generate?
├─ YES → Vector DB needed (you don't want to lose the work)
└─ NO → numpy can work (regenerating is fast)
Criterion 4: Concurrency (multiple users)
Simple rule:
# of concurrent users | Option
---------------------------|-------------------
1 user (development) | numpy enough
2-10 users | Gray zone
>10 concurrent users | Vector DB needed
>100 users | Vector DB mandatory
Why concurrency matters:
numpy isn't thread-safe for writes:
import numpy as np
from threading import Thread
embeddings = np.load('embeddings.npy')
# ❌ Race condition: multiple users adding docs
def add_doc(user_id, doc_embedding):
global embeddings
embeddings = np.vstack([embeddings, doc_embedding]) # ❌ Not thread-safe
np.save('embeddings.npy', embeddings) # ❌ Corruption risk
# Multiple concurrent requests
threads = [Thread(target=add_doc, args=(i, emb)) for i, emb in enumerate(new_docs)]
for t in threads: t.start()
Vector DB thread-safe:
import chromadb
client = chromadb.PersistentClient(path="./chroma_db")
collection = client.get_collection("docs")
# ✅ Thread-safe: multiple users can add concurrently
def add_doc(user_id, doc_embedding, doc_id):
collection.add(embeddings=[doc_embedding], ids=[doc_id]) # ✅ Safe
# Multiple concurrent requests → No problems
Evaluation:
How many users will use your system simultaneously?
├─ 1-2 (development/demo) → numpy enough
├─ 3-10 (small team) → numpy with locks (complicated) OR vector DB (simple)
└─ >10 (production) → Vector DB needed
Do you need to add/update docs while others are querying?
├─ YES → Vector DB needed (handles read/write concurrently)
└─ NO → numpy can work (read-only)
Complete decision matrix
Combining the 4 criteria
| Scale | Latency | Persistence | Concurrency | Decision |
|---|---|---|---|---|
| <10K | >1s | Not critical | 1 user | ✅ numpy enough |
| <10K | <500ms | Not critical | 1-5 users | ⚠️ numpy/SQL (gray zone) |
| 10K-100K | <500ms | Critical | >5 users | ⚠️ Vector DB recommended |
| >100K | <500ms | Critical | >10 users | ✅ Vector DB needed |
| >500K | <100ms | Critical | >50 users | ✅ Vector DB mandatory |
Use cases: When you DO need one
Case 1: Tech support chatbot (enterprise)
Requirements:
- 500,000 documentation articles (1.5M chunks)
- 1,000 employees using it simultaneously
- <3s total response (<500ms retrieval)
- 99.9% uptime (24/7)
Evaluation:
- Scale: 1.5M vectors → ✅ Vector DB needed
- Latency: <500ms → ✅ Vector DB needed
- Persistence: 99.9% uptime → ✅ Vector DB needed
- Concurrency: 1,000 users → ✅ Vector DB needed
Decision: ✅ Vector DB needed (4/4 criteria met)
Recommendation:
- Development: ChromaDB local (free, fast)
- Production: Pinecone managed ($200-500/mo) or ChromaDB self-hosted on a robust server
Case 2: Q&A over legal documents (startup)
Requirements:
- 50,000 legal documents (150K chunks)
- 50 internal lawyers using it
- <2s total response (<300ms retrieval)
- 99% uptime (business hours)
Evaluation:
- Scale: 150K vectors → ✅ Vector DB recommended
- Latency: <300ms → ✅ Vector DB recommended
- Persistence: 99% uptime → ✅ Vector DB recommended
- Concurrency: 50 users → ✅ Vector DB recommended
Decision: ✅ Vector DB recommended (4/4 criteria)
Recommendation:
- ChromaDB self-hosted (free, enough for 150K vectors)
- Or Pinecone ($70-150/mo) if they prefer managed
Case 3: Multi-tenant RAG system (SaaS)
Requirements:
- 100 clients, each with 10K-50K documents
- Total: 1M-5M vectors (aggregated)
- <100ms retrieval (competitive)
- Multi-tenancy (data isolation per client)
- 99.99% uptime (contractual SLA)
Evaluation:
- Scale: 1M-5M vectors → ✅ Vector DB mandatory
- Latency: <100ms → ✅ Vector DB mandatory
- Persistence: 99.99% uptime → ✅ Vector DB mandatory
- Concurrency: 100s-1000s users → ✅ Vector DB mandatory
- Plus: Multi-tenancy → ✅ Vector DB with a native feature
Decision: ✅ Vector DB mandatory + managed preferred
Recommendation:
- Pinecone managed ($500-2000/mo) - the best option for multi-tenant SaaS
- Or Weaviate Cloud ($300-1000/mo) - flexible, GraphQL API
- NOT ChromaDB self-hosted (requires manual multi-tenancy handling)
Case 4: Research paper search (personal)
Requirements:
- 100,000 scientific papers (300K chunks)
- 1 user (researcher)
- <1s retrieval (exploratory analysis)
- Local on a laptop (privacy)
Evaluation:
- Scale: 300K vectors → ⚠️ Gray zone (numpy takes ~500ms)
- Latency: <1s → ⚠️ numpy could work (~500ms acceptable for exploration)
- Persistence: Local laptop → ⚠️ Not critical (you tolerate reload)
- Concurrency: 1 user → ✅ numpy enough
Decision: ⚠️ Gray zone (2/4 criteria don't favor a vector DB)
Options:
-
numpy + pgvector (local Postgres):
- Moderate setup (install Postgres + pgvector)
- 50-80ms retrieval (enough for exploration)
- Better persistence than raw numpy
-
ChromaDB local:
- pip install chromadb (simple)
- 15-30ms retrieval (excellent)
- Native persistence
-
Raw numpy:
- pip install numpy (simplest)
- 500ms retrieval (acceptable for 1 user exploring)
- No persistence (60s reload after restart)
Recommendation: ChromaDB local (best simplicity/performance balance)
Clear signs that you need a vector DB
IF you answer "YES" to 3+ of these:
- ✅ You have >100K vectors (or you'll grow to that)
- ✅ You need <500ms retrieval latency
- ✅ You need >99% uptime (production service)
- ✅ You have >10 concurrent users
- ✅ You need metadata filtering (category, date, author)
- ✅ You need to add/update docs dynamically
- ✅ You need robust backup/restore
- ✅ You need monitoring (latency, throughput, usage)
→ A vector DB is needed
IF you answer "NO" to all of them:
- You only have <1K vectors
- Latency doesn't matter (batch processing)
- You don't need uptime (one-off script)
- A single user (development)
- You don't need advanced features
- You won't add docs dynamically
- You don't need backup/monitoring
→ numpy is enough
Summary
What you learned:
- ✅ Criterion 1: Scale - >100K vectors → vector DB needed
- ✅ Criterion 2: Latency - <500ms → vector DB recommended, <100ms → mandatory
- ✅ Criterion 3: Persistence - uptime >99% → vector DB needed
- ✅ Criterion 4: Concurrency - >10 users → vector DB needed
- ✅ Decision matrix - Combine the criteria to decide
Typical cases:
- Production RAG (enterprise): 4/4 criteria → Vector DB needed
- Prototype/MVP: 0-1/4 criteria → numpy enough
- Gray zone: 2/4 criteria → Evaluate trade-offs (simplicity vs performance)
Why it matters:
- Don't over-engineer: If numpy meets the requirements, use it (simplicity)
- Don't under-engineer: If you need a vector DB, don't waste time with numpy (performance)
- An informed decision = time saved
Next capsule: Now that you know when you DO need a vector DB, you'll see when you DON'T (cases where alternatives are better).
Additional resources
- Choosing a Vector Database - Decision framework
- ChromaDB vs Pinecone - Self-hosted vs managed
- RAG at Scale - Production considerations
- Vector DB Benchmarks - Performance comparisons
- Multi-tenant RAG - SaaS use case
- Vector Database Comparison - Landscape overview
Reading time: 6-8 minutes
Next: 06-when-you-do-not-need-a-vector-database.md