Vector Databases Explained: Pinecone, Chroma & pgvector

📖 11 min read · AI & Machine Learning · AI Prompt Builder →

Why Regular Databases Can't Do This

Traditional databases are great at exact matches: find all users where age = 30, or full-text search for documents containing "machine learning". But they can't answer questions like "find me documents that are semantically similar to this query" — because they don't understand meaning.

Vector databases solve this by storing data as high-dimensional vectors (embeddings) and enabling fast approximate nearest neighbor (ANN) search — finding the most similar vectors to a query vector in milliseconds, even across millions of records.

How Embeddings Capture Meaning

An embedding model converts text (or images, audio, etc.) into a fixed-size vector of numbers. Similar content produces similar vectors — measured by cosine similarity or dot product.

// Conceptual example (actual vectors have 1536 dimensions)
"dog" → [0.23, -0.45, 0.12, 0.67, ...]
"puppy" → [0.25, -0.43, 0.14, 0.65, ...] // Very similar!
"cat" → [0.21, -0.40, 0.18, 0.60, ...] // Somewhat similar
"database" → [-0.12, 0.34, -0.56, 0.23, ...] // Very different

ANN Algorithms: How Fast Search Works

Brute-force search (compare query to every vector) is too slow at scale. Vector databases use ANN algorithms:

HNSW (Hierarchical Navigable Small World)

Graph-based algorithm. Builds a multi-layer graph where each node connects to its nearest neighbors. Very fast queries, high recall. Used by Chroma, Weaviate, Qdrant.

IVF (Inverted File Index)

Clusters vectors into groups, searches only the most relevant clusters. Good for very large datasets. Used by Faiss, Pinecone.

PQ (Product Quantization)

Compresses vectors to reduce memory usage. Trades some accuracy for much lower RAM requirements. Often combined with IVF.

Flat (Brute Force)

Exact search — compares query to every vector. 100% recall but O(n) time. Only practical for small datasets (<100K vectors).

Pinecone: Managed Vector Database

import { Pinecone } from '@pinecone-database/pinecone';

const pc = new Pinecone({ apiKey: process.env.PINECONE_API_KEY });
const index = pc.index('my-index');

// Upsert vectors
await index.upsert([
  { id: 'doc1', values: [0.1, 0.2, ...], metadata: { text: 'Hello world', source: 'docs' } },
  { id: 'doc2', values: [0.3, 0.4, ...], metadata: { text: 'AI is amazing', source: 'blog' } },
]);

// Query for similar vectors
const results = await index.query({
  vector: queryEmbedding,  // Your query converted to embedding
  topK: 5,
  includeMetadata: true,
  filter: { source: { $eq: 'docs' } },  // Optional metadata filter
});

results.matches.forEach(match => {
  console.log(match.score, match.metadata.text);
});

Chroma: Local Development

import { ChromaClient, OpenAIEmbeddingFunction } from 'chromadb';

const client = new ChromaClient(); // Runs locally by default

const embedder = new OpenAIEmbeddingFunction({
  openai_api_key: process.env.OPENAI_API_KEY,
  openai_model: 'text-embedding-3-small',
});

const collection = await client.getOrCreateCollection({
  name: 'my-docs',
  embeddingFunction: embedder,
});

// Add documents (Chroma handles embedding automatically)
await collection.add({
  ids: ['doc1', 'doc2'],
  documents: ['Hello world', 'AI is amazing'],
  metadatas: [{ source: 'docs' }, { source: 'blog' }],
});

// Query by text (Chroma embeds the query automatically)
const results = await collection.query({
  queryTexts: ['What is artificial intelligence?'],
  nResults: 3,
});

pgvector: If You Already Use PostgreSQL

-- Enable the extension
CREATE EXTENSION IF NOT EXISTS vector;

-- Create table with vector column
CREATE TABLE documents (
  id SERIAL PRIMARY KEY,
  content TEXT,
  embedding vector(1536)  -- OpenAI text-embedding-3-small dimension
);

-- Insert with embedding
INSERT INTO documents (content, embedding)
VALUES ('Hello world', '[0.1, 0.2, ...]'::vector);

-- Find 5 most similar documents (cosine similarity)
SELECT content, 1 - (embedding <=> '[0.15, 0.25, ...]'::vector) AS similarity
FROM documents
ORDER BY embedding <=> '[0.15, 0.25, ...]'::vector
LIMIT 5;

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

Choosing the Right Vector Database

Prototyping / local dev→ ChromaZero setup, runs in-memory or on disk, free
Production, managed, scalable→ PineconeFully managed, auto-scaling, good SLA
Already using PostgreSQL→ pgvectorNo new infrastructure, ACID transactions, familiar SQL
Hybrid search (vector + keyword)→ Weaviate or ElasticsearchBuilt-in BM25 + vector search combination
Self-hosted, high performance→ QdrantRust-based, very fast, good filtering, open source
Billions of vectors→ MilvusDesigned for massive scale, distributed architecture

Build RAG Pipelines with DevBench

Use our AI tools to prototype prompts and count tokens for your vector search applications.