Home 01 · Vector DB 02 · LLM Frameworks 03 · AI Systems 04 · Prompt & Tuning 05 · AI Testing 06 · AI Architect 07 · AI Integration

What problem vector databases solve

Every embedding model turns text, images, or other content into a list of floating-point numbers — a vector — positioned in high-dimensional space so that semantically similar things sit close together. A vector database stores millions or billions of these vectors and answers one core question fast: given this query vector, what are the K closest vectors in the index?

This single operation, approximate nearest neighbor (ANN) search, underpins RAG pipelines, semantic search, recommendation systems, deduplication, anomaly detection, and image similarity search. The "database" part is really index management plus metadata filtering plus storage at scale.

Core vocabulary

TermMeaning
EmbeddingNumeric vector representation of content, produced by a model (e.g. OpenAI, Cohere, sentence-transformers)
ANN searchApproximate Nearest Neighbor — finds "close enough" matches fast, trading perfect recall for speed
HNSWHierarchical Navigable Small World — graph-based ANN index, most common in production today
IVFFlatInverted File index — clusters vectors into buckets, searches only relevant buckets
Cosine similarityMeasures the angle between two vectors; most common metric for text embeddings
Recall@KOf the K results returned, how many are truly relevant — core retrieval quality metric
Hybrid searchCombining dense vector search with sparse keyword search (e.g. BM25) for better precision
O(log n)
approx. HNSW query scaling
cosine / dot / L2
common distance metrics
RAG
most common production use case

PostgreSQL + pgvector

pgvector is an open-source Postgres extension that adds a native vector column type and similarity operators directly into SQL. Instead of standing up new infrastructure, embeddings live in the same table as the rest of your relational data.

What you can actually build

-- enable extension
CREATE EXTENSION vector;

CREATE TABLE documents (
  id serial PRIMARY KEY,
  content text,
  account_id int,
  status text,
  embedding vector(1536)
);

-- HNSW index for ANN search
CREATE INDEX ON documents
  USING hnsw (embedding vector_cosine_ops);

-- query: nearest neighbors + relational filter
SELECT content
FROM documents
WHERE status = 'open' AND account_id = 42
ORDER BY embedding <=> '[0.012, -0.045, ...]'
LIMIT 5;
Advantages
  • No new infrastructure — reuses existing Postgres ops, backups, monitoring
  • ACID transactions; vectors and relational data stay consistent
  • Free, open source, no per-query or per-vector billing
  • Native SQL joins between vectors and structured data in one query
  • Good fit for low-to-mid millions of vectors
Disadvantages
  • Performance degrades at very large scale (100M+ vectors) vs. purpose-built engines
  • HNSW/IVFFlat index tuning (m, ef_construction, lists) is manual
  • Horizontal scaling requires extra work (Citus, read replicas, sharding)
  • Index builds can be slow and memory-hungry on large tables

Pinecone

Pinecone is a fully managed, purpose-built vector database delivered as an API. You push vectors via SDK calls; Pinecone handles index construction (HNSW-based), sharding, replication, and scaling — there's no underlying database to administer.

What you can actually build

import { Pinecone } from "@pinecone-database/pinecone";
const pc = new Pinecone({ apiKey: process.env.PINECONE_API_KEY });
const index = pc.index("support-tickets");

await index.namespace("acct-42").upsert([
  { id: "doc1", values: embedding, metadata: { status: "open" } }
]);

const results = await index.namespace("acct-42").query({
  vector: queryEmbedding,
  topK: 5,
  filter: { status: { "$eq": "open" } }
});
Advantages
  • Purpose-built for vector search at massive scale, low and predictable latency
  • Fully managed — no index tuning, no capacity planning, no patching
  • Strong ecosystem integration (LangChain, LlamaIndex)
  • Built-in namespaces for clean multi-tenancy
  • Hybrid search support out of the box
Disadvantages
  • Cost scales meaningfully with vector count and query volume
  • Vendor lock-in; migrating off later has real engineering cost
  • Data lives outside your existing infrastructure — matters for compliance contexts like HIPAA, verify BAA support directly with current docs
  • No relational joins; metadata filtering is not a substitute for SQL
  • Adds an operational dependency / another vendor in the stack

Decision framing

SituationLean toward
Already running Postgres, moderate scale, need relational + vector togetherpgvector
MVP / early-stage product, cost-sensitivepgvector
Billions of vectors, strict low-latency SLAPinecone
Want zero ops overhead, small teamPinecone
Strict data residency / compliance constraints on a self-hosted stackpgvector (self-hosted)

ANN Algorithms & Index Tuning

Approximate Nearest Neighbor (ANN) search is what makes vector databases fast. Instead of comparing a query vector against every stored vector (exact search, O(n)), ANN algorithms build index structures that navigate to approximate matches in O(log n) or sub-linear time, trading a small, tunable amount of recall for massive speed gains.

HNSW vs IVFFlat — the two you need to know

HNSW

Hierarchical Navigable Small World — builds a multi-layer proximity graph. Upper layers are sparse long-range links for fast navigation; lower layers are dense short-range links for accuracy.

  • Best query speed at high recall — production default
  • Index builds in memory; RAM-heavy at large scale
  • Supports incremental inserts without full rebuild
  • Key params: m (edges per node), ef_construction (build-time search width), ef_search (query-time search width)
IVFFlat

Inverted File Index — k-means clusters vectors into lists buckets; queries only search probes nearest bucket centroids.

  • Lower memory footprint than HNSW at large scale
  • Requires training pass before indexing (k-means)
  • Recall depends heavily on probes value — higher = better recall, slower query
  • Key params: lists (number of clusters), probes (clusters searched per query)

HNSW parameter tuning cheat-sheet

ParameterDefaultEffect of increasingTradeoff
m16More edges per node → better recallMore memory, slower build
ef_construction64Wider search at build time → better index qualityMuch slower index build, same query speed
ef_search40Wider search at query time → better recallHigher query latency

Distance metrics — which to choose

MetricOperator (pgvector)When to use
Cosine similarity<=>Text embeddings — cares about direction, not magnitude. Most common for RAG.
Dot product<#>When vectors are pre-normalized; equivalent to cosine, slightly faster
Euclidean (L2)<->Image embeddings, spatial data — magnitude matters
Manhattan (L1)<+>Sparse or high-dimensional data where L2 suffers from curse of dimensionality

Index scaling math

O(log n)
HNSW query time complexity
d × 4 bytes
memory per float32 vector (d = dimensions)
1536-dim
OpenAI ada-002 — 6 KB per vector
~60 GB
RAM for 10M × 1536-dim HNSW index (estimate)
-- pgvector: HNSW index with tuned parameters
CREATE INDEX ON documents
  USING hnsw (embedding vector_cosine_ops)
  WITH (m = 24, ef_construction = 100);

-- Set query-time search width per session
SET hnsw.ef_search = 80;

-- IVFFlat alternative for lower memory budget
CREATE INDEX ON documents
  USING ivfflat (embedding vector_cosine_ops)
  WITH (lists = 200);

-- Tune probes at query time
SET ivfflat.probes = 10;

Choosing between HNSW and IVFFlat

ScenarioRecommendation
Under 1M vectors, need fast insertsHNSW — better recall, handles incremental inserts well
Over 10M vectors, RAM is constrainedIVFFlat — lower memory footprint, tune probes for recall
Need best possible recall at any costHNSW with high m and ef_search
Batch-only workload, large static datasetIVFFlat — training cost is one-time
Production default with no special constraintsHNSW — it's the industry standard for good reason

Hybrid Search

Pure dense vector search excels at semantic similarity but misses exact-term matches — a user searching for "GPT-4o-mini" or a specific product SKU might get semantically adjacent results when they need an exact keyword hit. Hybrid search combines dense vector search with sparse keyword search (typically BM25) so you get both semantic understanding and lexical precision.

Query
Dense embed → ANN search
+
Sparse BM25 → keyword search
Reciprocal Rank Fusion
Re-ranked results

Dense vs Sparse vs Hybrid

ApproachStrengthsWeaknesses
Dense (vector) onlySemantic understanding, handles synonyms, paraphrasesMisses exact terms, codes, SKUs, proper nouns
Sparse (BM25/TF-IDF) onlyExact keyword matching, interpretable, fastNo semantic understanding, misses synonyms
Hybrid (both)Best of both — semantic + lexical precisionMore complex pipeline, latency of both searches

Reciprocal Rank Fusion (RRF)

RRF is the most common way to merge dense and sparse result sets. Each document gets a score based on its rank in each list, then scores are summed. It's robust — it doesn't require calibrating score scales between the two systems, which is notoriously hard.

-- RRF formula: score(d) = sum over each list of 1 / (k + rank(d))
-- k=60 is the standard constant (reduces sensitivity to top-rank variance)

-- Example: merging dense rank 2 + sparse rank 5
-- RRF score = 1/(60+2) + 1/(60+5) = 0.0161 + 0.0154 = 0.0315

Re-ranking (cross-encoder)

After ANN retrieval gives you a candidate set (e.g. top-50), a cross-encoder re-ranker scores each candidate against the full query in context — much more accurate than bi-encoder similarity, but too slow to run on the full corpus. This two-stage pattern is the production standard for high-precision retrieval.

ANN retrieval (fast, approximate)
top-50 candidates
Cross-encoder re-rank (slow, precise)
top-5 final results
LLM generation
grounded answer
from sentence_transformers import CrossEncoder

reranker = CrossEncoder("cross-encoder/ms-marco-MiniLM-L-6-v2")

# candidates = [(doc_text, score), ...] from ANN retrieval
pairs = [(query, doc) for doc, score in candidates]
rerank_scores = reranker.predict(pairs)

# Sort by re-ranker score and take top-5
ranked = sorted(zip(candidates, rerank_scores),
                key=lambda x: x[1], reverse=True)[:5]
When Hybrid Search Pays Off
  • Queries mixing semantic intent with exact terms (product codes, medical codes, claim IDs)
  • Domain-specific terminology the embedding model may not handle well
  • Legal, medical, or financial documents where exact phrase matching matters
  • Multilingual content where keyword match supplements semantic understanding
When Dense Alone Is Sufficient
  • General-purpose Q&A where queries are natural language sentences
  • The embedding model was fine-tuned on your domain
  • Latency budget is tight — hybrid adds the cost of two searches
  • Index is small enough that recall@K is already high with dense search alone

Hybrid search in Pinecone

// Pinecone supports native sparse-dense hybrid search
const results = await index.query({
  vector: denseEmbedding,          // dense component
  sparseVector: {                  // sparse BM25 component
    indices: [102, 983, 1204],
    values:  [0.72, 0.45, 0.31]
  },
  topK: 10,
  alpha: 0.7   // 0 = pure sparse, 1 = pure dense
});

Production Patterns

Getting vector search working in a notebook is straightforward. Getting it to stay accurate, fast, and compliant in a production system over months is where most teams underinvest. These are the patterns that matter once you're past the prototype stage.

1 · Embedding model versioning

Vectors from different embedding models live in incomparable semantic spaces. Mixing them silently destroys retrieval quality without any error being thrown.

  • Store embedding_model and embedding_version as metadata on every vector
  • When switching models: maintain a separate index per version, or run a full re-embed + re-index migration
  • Never mix vectors from different models in one similarity search
  • Gate model upgrades behind a retrieval quality evaluation (Ragas recall@K) before cutting over
-- pgvector: track model version in the same table
ALTER TABLE documents ADD COLUMN embedding_model TEXT;
ALTER TABLE documents ADD COLUMN embedding_version TEXT;

-- Always filter by version at query time
SELECT content FROM documents
WHERE embedding_model = 'text-embedding-3-small'
  AND embedding_version = 'v1'
ORDER BY embedding <=> $1 LIMIT 5;

2 · Multi-tenancy patterns

Hard partitioning (preferred for HIPAA)
  • Pinecone: one namespace per tenant
  • pgvector: one table per tenant, or tenant_id in a partitioned table
  • Queries only scan tenant's own vectors — no cross-tenant perf leakage
  • Simpler data isolation audit — clear boundary for compliance
  • Deletion is a table/namespace drop — clean and verifiable
Shared index + metadata filter
  • All tenants in one index, filtered by tenant_id metadata
  • Operationally simpler — one index to manage
  • Performance risk: one noisy tenant's query load can affect others
  • Harder to prove data isolation in a compliance audit
  • Deletion requires filtering and removing vectors — more error-prone

3 · Index staleness management

One of the most common silent failures: source data is updated or deleted but the vector index isn't. The model then retrieves stale or incorrect context with high confidence.

Update patternStrategy
Document editedRe-embed updated content → upsert vector with same ID (overwrites)
Document deletedDelete vector by ID immediately — don't wait for a batch job
Bulk data refreshWrite to a shadow index, run eval, swap alias to shadow, drop old
Embedding model upgradeRe-embed all documents in new model → new index → eval → cutover

4 · HIPAA & compliance checklist

  • Encryption at rest and in transit — confirm at the infrastructure level, not just assumed
  • BAA with managed vector DB vendors — Pinecone supports HIPAA with Enterprise tier + BAA; verify current docs before assuming
  • PHI in embeddings — embedding models can encode PHI in vectors; the vector index is a PHI store if the source docs contain PHI
  • Audit logging — every query, upsert, and deletion should be logged with user identity and timestamp
  • Access controls — row-level security in pgvector; namespace-level access policies in Pinecone
  • Self-hosted preference — for highest compliance confidence, self-hosted pgvector within your existing compliant infra avoids vendor BAA dependencies

5 · Monitoring in production

What to monitorSignalTool
Retrieval qualitySample queries → score precision@K and context relevanceRagas, DeepEval
Embedding driftQuery vector distribution shifting from index distributionEvidently AI
Index stalenessSource doc update lag vs index update lagCustom metric / Datadog
Query latency p95ANN search time trending up as index growsAPM / Prometheus
Index memory usageHNSW index RAM approaching instance limitCloud metrics

6 · Cost optimization

Reduce dimensionality
  • Use smaller embedding models (1536 → 768 → 384 dimensions)
  • PCA or Matryoshka embeddings for truncatable representations
  • Cuts memory and compute roughly proportionally
Vector quantization
  • Product Quantization (PQ) compresses vectors from float32 to compact codes
  • Scalar Quantization (SQ8) reduces each dimension from 4 bytes to 1 byte
  • 10–20× memory reduction; small recall tradeoff — benchmark before committing

Vector Database Comparison

pgvector and Pinecone are the two most common choices, but the broader landscape has several strong options. Understanding the key differentiators lets you make an informed recommendation — and defend it in an interview.

Full comparison matrix

DatabaseTypeIndexScaleHostingBest for
pgvector Extension (Postgres) HNSW, IVFFlat Low–Mid (tens of millions) Self-hosted / managed (Supabase, Neon) Existing Postgres users, relational + vector queries, HIPAA self-hosted
Pinecone Purpose-built managed HNSW (proprietary) Billions of vectors Fully managed SaaS Large scale, low-ops, multi-tenant RAG with namespaces
Weaviate Purpose-built OSS HNSW + BM25 hybrid High Self-hosted or managed (Weaviate Cloud) Built-in hybrid search, GraphQL API, multi-modal embeddings
Qdrant Purpose-built OSS HNSW High Self-hosted or managed Rust-based performance, rich payload filtering, on-prem compliance
Chroma Purpose-built OSS HNSW (via hnswlib) Low–Mid Embedded or self-hosted Local dev, prototyping, LangChain/LlamaIndex default in tutorials
Milvus Purpose-built OSS HNSW, IVF, DiskANN Billions of vectors Self-hosted (k8s) or Zilliz cloud Enterprise scale on-prem, multiple index type support

Decision tree

QuestionIf Yes →
Already running Postgres in production?pgvector first — zero new infrastructure
Scale > 100M vectors with strict latency SLA?Pinecone or Milvus
Need built-in hybrid dense + sparse search?Weaviate or Pinecone
Air-gapped / strict data residency, not Postgres?Qdrant or Milvus self-hosted
Just prototyping / local dev?Chroma — simplest setup, no server needed
HIPAA, self-hosted, production scale?pgvector (Postgres infra you already control)

The interview-ready summary

Start with pgvector. It's free, uses infrastructure you already have, and is sufficient for the majority of production RAG systems. Move to a purpose-built database only when you have a concrete requirement — scale, latency SLA, or operational constraints — that pgvector demonstrably can't meet. Chroma is fine for local development but shouldn't be the first choice for production. Weaviate and Qdrant are strong self-hosted alternatives when you need purpose-built performance without a managed-SaaS dependency. Pinecone is the path of least ops resistance at large scale, but verify compliance posture and model the cost before committing.

Production-Level Interview Q&A

Click a question to expand the answer.

How would you decide between pgvector and Pinecone for a new RAG system?
Weigh expected vector count and growth rate, latency requirements, whether vectors need to be joined with relational data, existing team infrastructure and expertise, compliance/data residency constraints, and projected cost at scale. A senior-level answer also pushes back on premature optimization: start with pgvector for an MVP or moderate-scale system, and migrate to a purpose-built engine like Pinecone only once scale or latency actually demands it — not because it's trendy.
What's the difference between exact nearest neighbor search and ANN, and why does production use ANN?
Exact (brute-force) search compares the query vector against every stored vector — perfectly accurate but O(n), so it doesn't scale past tens of thousands of vectors. ANN algorithms like HNSW or IVFFlat build index structures that trade a small, controllable amount of recall for large speed gains, which is necessary once you're past a few hundred thousand vectors. Production systems almost always use ANN and monitor recall to make sure the tradeoff stays acceptable.
How do you handle embedding model versioning in production?
This is a common production gotcha: vectors from different embedding models (or even different versions/fine-tunes of the same model) live in different semantic spaces and are not directly comparable. Track embedding model version as metadata on every vector. When switching models, either maintain separate indexes per version or run a full re-embed + re-index migration — never mix vectors from different models in one similarity search.
How do you test or validate a RAG retrieval pipeline?
Build a labeled evaluation set of representative queries with known-relevant documents. Measure precision@K, recall@K, and MRR (mean reciprocal rank) against that set. Tools like Ragas or DeepEval can automate scoring of whether retrieved context is actually relevant to the query, and whether the final generated answer is grounded in that context. This maps directly onto ETL validation thinking — you're validating that the transform (embed + retrieve) step produces correct output, just judged by semantic relevance instead of exact-match.
What happens to query performance and cost as the index grows, and how do you mitigate it?
HNSW-based indexes scale roughly logarithmically in query time, but memory usage grows roughly linearly with vector count × dimensionality, which becomes a real cost and infrastructure constraint at scale. Mitigations: dimensionality reduction, vector quantization (compressed representations like product quantization), partitioning/sharding by tenant or category, and tuning index parameters (HNSW's m and ef_construction) to balance build time, query latency, and recall.
How would you secure a vector database in a HIPAA-regulated environment?
Encryption at rest and in transit, strict access controls and audit logging, confirming the embedding model itself doesn't leak PHI back out through its outputs, and a signed BAA with any managed vendor (verify current HIPAA/BAA support directly against the provider's docs rather than assuming). In a compliance-sensitive environment, self-hosted pgvector inside infrastructure you already control can be the lower-risk default versus a third-party managed service, unless that vendor's compliance posture is explicitly verified.
What's a common production failure mode with vector search, and how do you catch it?
Silent retrieval degradation: the system doesn't throw an error, it just quietly returns less-relevant context, and the LLM generates a confident but wrong answer downstream. This isn't caught by upfront accuracy testing alone — it requires ongoing retrieval quality monitoring, sampling live queries and scoring relevance over time, since embedding drift, stale data, or index corruption degrade quality gradually rather than all at once.
Walk through how you'd design a multi-tenant RAG system's vector storage.
Two main patterns: namespace/partition-per-tenant (e.g. Pinecone namespaces, or a tenant_id column + filter in pgvector) keeps tenants isolated and queries fast since each search only scans that tenant's vectors. The alternative — one shared index with tenant_id as metadata filtered at query time — is simpler operationally but can leak performance issues across tenants and creates a larger blast radius for data isolation bugs. For HIPAA-adjacent work, hard partitioning per tenant is the safer default.
Why might cosine similarity be preferred over Euclidean distance for text embeddings?
Cosine similarity measures the angle between vectors, not their magnitude, which matters because many embedding models produce vectors whose length can vary with content length or other artifacts unrelated to meaning. For normalized embeddings, cosine and dot product give equivalent rankings; Euclidean distance is more common for spatial or image-based embeddings where magnitude itself carries meaningful information.
How do you debug a case where retrieval returns irrelevant results despite a 'correct' query?
Systematic approach: verify the query and stored vectors come from the same embedding model/version; check the index hasn't gone stale (deleted or updated source docs not reflected in the index); inspect actual returned similarity scores — low scores across the board suggest a real semantic mismatch, not a bug; check metadata filters aren't silently over-restricting; and confirm chunking strategy isn't splitting relevant content across boundaries in a way that destroys context.