All articles
Guides12 min readJune 4, 2026

Vector Databases and Embeddings Explained

An embedding turns text, images, or other data into a list of numbers (a vector) that captures meaning, and a vector database stores those vectors and finds the closest matches fast. Together they power semantic search, retrieval-augmented generation, and agent memory: you search by meaning instead of exact keywords. This guide covers cosine similarity, HNSW and IVF indexes, chunking, metadata filtering, and when plain Postgres with pgvector beats a dedicated vector database.

Quick answer

An embedding turns text, images, or other data into a list of numbers (a vector) that captures meaning, and a vector database stores those vectors and finds the closest matches fast. Together they power semantic search, retrieval-augmented generation, and agent memory: you search by meaning instead of exact keywords. This guide covers cosine similarity, HNSW and IVF indexes, chunking, metadata filtering, and when plain Postgres with pgvector beats a dedicated vector database.

An embedding is a list of numbers that represents the meaning of a piece of data, and a vector database is the system that stores those numbers and finds the closest ones quickly. Put them together and you can search by meaning instead of by exact words. Ask for "refund policy for damaged items" and you get the right document even if it never uses the word "refund."

Here is the mechanism in one breath. An embedding model reads your text and outputs a vector, often 384, 768, or 1,536 numbers long. Similar meanings land near each other in that high-dimensional space. To search, you embed the query the same way, then ask the database for the stored vectors that sit closest to it. "Closest" is usually measured with cosine similarity, the angle between two vectors. A vector database makes that nearest-neighbor lookup fast using an index like HNSW or IVF, so you are not comparing the query against every record one by one.

This is the engine behind a lot of what people call "AI" right now. Retrieval-augmented generation (RAG) uses it to fetch relevant context before a language model answers. Semantic search uses it to rank results by meaning. Agent memory uses it to recall what happened in earlier conversations. The concepts are the same in all three cases: embed, store, search by similarity, filter by metadata. The rest of this guide walks through each piece, shows where teams trip up, and gives you a clear rule for when plain Postgres is enough versus when you need a dedicated vector database.

What is an embedding, really?

An embedding is a fixed-length array of floating-point numbers that a trained model produces from your input. The model has learned, from huge amounts of text, to place inputs with similar meaning near each other in a geometric space. "Cancel my subscription" and "how do I end my plan" produce vectors that point in nearly the same direction, even though they share almost no words.

The length of the vector is its dimensionality. Common text models output 384 dimensions (small and fast), 768 (a frequent middle ground), or 1,536 and higher (more nuance, more storage and compute). Higher dimensions can capture finer distinctions, but they cost more to store and search, and past a point they add little. Pick based on your accuracy needs and your budget, not on the assumption that bigger is always better.

Embeddings are not limited to text. The same idea works for images, audio, code, and product records. A multimodal model can place a photo of a red sneaker and the phrase "red running shoe" close together. What matters is consistency: you must embed your stored data and your queries with the same model and version. Mix two models and the geometry no longer lines up, so your similarity scores become noise. Re-embedding everything after a model change is one of the most common, and most painful, migrations teams forget to plan for.

An embedding is meaning turned into coordinates. Search becomes geometry: find the points nearest the question.

How does similarity search with cosine similarity work?

Once your data is a set of vectors, finding relevant results means finding the vectors closest to your query vector. The most common distance metric for text embeddings is cosine similarity, which measures the angle between two vectors rather than the straight-line distance between them. Two vectors that point the same way score close to 1; unrelated ones score near 0; opposite meanings approach -1.

Cosine similarity is popular because it ignores magnitude and focuses on direction, which suits text where the "strength" of a vector is less meaningful than its orientation. Other metrics exist: dot product is faster and is equivalent to cosine when vectors are normalized to unit length, and Euclidean distance (L2) is sometimes used for image or spatial data. The key rule is to match the metric your embedding model was trained or recommended for. Many text models assume cosine or normalized dot product, and using the wrong one quietly degrades quality.

From a question to an answer: the retrieval flow
  1. 1

    Chunk

    Split source documents into passages of a few hundred tokens with slight overlap.

  2. 2

    Embed

    Run each chunk through the embedding model to get a vector, and attach metadata.

  3. 3

    Store

    Write vectors plus metadata into the vector index (HNSW or IVF).

  4. 4

    Query

    Embed the user's question with the same model to get a query vector.

  5. 5

    Search

    Find the nearest vectors by cosine similarity, filtered by metadata.

  6. 6

    Answer

    Pass the top chunks to the language model as grounding context.

A typical RAG and semantic-search pipeline. Steps 1 to 2 run once per document; steps 3 to 6 run on every query.

Why you need an ANN index: HNSW and IVF

Comparing a query against every stored vector (an exact, or "brute force," search) is accurate but slow once you have millions of records. Approximate nearest neighbor (ANN) indexes trade a tiny amount of recall for a huge speedup. They organize vectors so the search only inspects a small, promising slice of the data. The two indexes you will meet most often are HNSW and IVF.

HNSW (Hierarchical Navigable Small World) builds a layered graph where each vector links to nearby neighbors. A search starts at the top, sparse layer and walks downhill toward denser ones, hopping closer to the answer at each step. As of 2026 it is the default for most production workloads: it gives an excellent speed-to-recall tradeoff, handles high dimensions well, needs no training step, and supports inserts on the fly. The cost is higher memory use and slower index builds.

IVF (Inverted File index, often IVFFlat in Postgres) takes a different route. It clusters vectors into a set number of lists, then at query time it only searches the lists nearest the query. It builds faster, uses less memory, and is simpler to insert into, which is why it earns its place on very large, mostly static datasets where memory or build time dominates the cost model. The downside is a weaker speed-recall tradeoff and a training step that assumes your data distribution is stable. Two knobs matter: how many lists you create, and how many you probe per query. More probes means better recall but slower queries.

FactorHNSW (graph)IVF / IVFFlat (clustered)
Speed-recall tradeoffBest in class, especially high-dimensionalGood, but generally below HNSW
Index build timeSlowerFaster
Memory footprintHigherLower
Inserts and updatesHandles streaming inserts wellSimpler inserts, but needs periodic rebuilds
Training stepNone (build on an empty table)Requires a representative sample to train
Best fitNew systems, dynamic data, high recallVery large, mostly static, memory-constrained
How the two most common ANN index types compare. Use it as a starting point, then benchmark on your own data.

What does a vector database actually do?

A vector database stores embeddings, indexes them for fast similarity search, and runs that search alongside ordinary filters and metadata. That last part is what separates a real database from a raw index. In production you almost never want "the most similar chunk anywhere." You want "the most similar chunk in this customer's documents, from the last 90 days, marked public." The vector store has to combine the semantic search with structured constraints.

Most vector stores give you a few core capabilities. Knowing them helps you evaluate options without getting lost in marketing pages.

  • Storage and indexing: it persists vectors and builds an ANN index (usually HNSW) so queries stay fast as data grows, instead of degrading into a full scan.
  • Metadata filtering: it stores fields next to each vector (tenant ID, document type, date, ACL tags) and filters on them, because semantic relevance without access control is a security incident waiting to happen.
  • CRUD and freshness: it lets you insert, update, and delete vectors as your source data changes, so stale or deleted content does not keep surfacing in results.
  • Hybrid search: many stores blend vector similarity with keyword (BM25-style) search, which catches exact terms like SKUs, error codes, and names that pure semantic search can miss.
  • Scaling and operations: it handles sharding, replication, and backups so search keeps working as you move from one million to one hundred million vectors.

A bare index finds similar vectors. A vector database finds similar vectors this user is allowed to see, right now.

Chunking and metadata: where retrieval quality is won or lost

Before anything gets embedded, long documents get split into smaller passages called chunks. This matters more than most teams expect. Embed a whole 40-page PDF as one vector and you get a blurry average of every topic in it, useless for pinpoint retrieval. Embed each sentence in isolation and you lose the surrounding context that made it meaningful. The sweet spot is usually a few hundred tokens per chunk with a small overlap between neighbors so a thought that straddles a boundary is not cut in half.

Good chunking respects structure. Splitting on headings, paragraphs, or list items keeps related ideas together far better than slicing every N characters. For a support knowledge base, one article section per chunk often works well. For code, function or class boundaries make better seams than arbitrary line counts.

Metadata is the other half of the equation, and it is what makes a vector store safe for multi-tenant and enterprise use. Every chunk should carry fields like source URL, document ID, owner, tenant, timestamp, and permission tags. At query time you filter on those before or during the similarity search. This is how an AI agent answering a question for one customer never retrieves another customer's data, even if the two documents are semantically close. When OnPilot agents retrieve context to take an action, that retrieval runs inside least-privilege RBAC and leaves an audit trail, so a search can never quietly cross a permission boundary.

How embeddings power RAG and agent memory

Retrieval-augmented generation is the headline use case. A language model only knows what was in its training data plus what you put in the prompt. RAG fills that gap: embed the user's question, retrieve the most relevant chunks from your own content, and hand them to the model as grounding. The model answers from real, current, company-specific material instead of guessing. This is how a support agent cites your actual return policy rather than a plausible-sounding invention.

Agent memory uses the same machinery for a different goal: continuity. When an agent finishes a task or a conversation, the useful facts can be embedded and stored, then recalled later by similarity when a related topic comes up. "What did we decide about the Acme renewal?" pulls back the relevant earlier exchange even across sessions. The vector store becomes the agent's long-term recall layer, while metadata and access controls keep one user's memory from leaking into another's.

A quick scenario ties it together. A support rep asks an AI agent, "Has this customer hit their API rate limit before, and what did we tell them?" The agent embeds that question, runs a similarity search scoped by metadata to that customer's history, retrieves the two relevant past tickets, and drafts a reply grounded in what was actually said. With approvals turned on, the rep reviews and confirms before anything is sent. Embeddings did the recall, metadata enforced the boundary, and a human-in-the-loop step kept control.

How fast is approximate search versus brute force?

The whole reason ANN indexes exist is latency at scale. The numbers below are illustrative and directional, meant to show the shape of the tradeoff rather than promise specific timings on your hardware. The pattern holds in practice: exact search stays accurate but slows down roughly in proportion to data size, while a graph index keeps query latency low by inspecting only a fraction of the vectors, at the cost of a few percent of recall you can tune back.

Query latency by approach at roughly one million vectors
Brute-force exact scan
~850 ms
IVF (few probes)
~35 ms
IVF (more probes)
~60 ms
HNSW (tuned)
~8 ms

Illustrative figures to show the tradeoff, not a benchmark. Actual latency depends on dimensions, hardware, and index parameters. Lower is better.

The lesson is not "HNSW always wins." It is that you should never run brute force in production past a few hundred thousand vectors, and that the recall you give up to ANN is a dial you control. If you need higher recall, search more of the graph or probe more lists and accept slightly higher latency. If you need lower latency, do the reverse. Measure recall against an exact baseline on a sample so you know exactly what you are trading.

When is pgvector enough, and when do you need a dedicated vector database?

Reach for plain Postgres with the pgvector extension first. It puts vector columns and ANN indexes (both HNSW and IVFFlat) right inside the database you probably already run, which means one system to operate, transactional consistency between your vectors and your relational rows, and no separate sync job to keep them aligned. For most teams in 2026, pgvector comfortably handles RAG and agent-memory workloads into the tens of millions of vectors with moderate query volume.

Move to a dedicated vector database (Qdrant, Milvus, Pinecone, Weaviate, and similar) only when you can name the specific bottleneck forcing the move. The usual triggers are real scale and real latency demands, not hype.

  • Use pgvector when vectors are a feature inside a larger app, your data fits in the tens of millions, and you value atomic updates between relational and vector data over raw search throughput.
  • Use pgvector when your team already runs Postgres and you would rather tune one system than operate two, since fewer systems means fewer sync failures and fewer ways for the two stores to disagree.
  • Move to a dedicated vector DB when you push past roughly 50 to 100 million vectors and HNSW rebuild times in Postgres become a real operational drag.
  • Move to a dedicated vector DB when vector search is your primary workload and you need single-digit-millisecond p99 latency at high query volume.
  • Move to a dedicated vector DB when you need heavy filtered ANN at scale or built-in features like advanced hybrid search, quantization, and horizontal sharding that purpose-built engines ship out of the box.

Default to pgvector. Switch to a dedicated vector database only when you can point at the bottleneck that broke it.

Common mistakes that quietly wreck retrieval

Most retrieval problems are not exotic. They come from a handful of avoidable errors that show up as "the AI gives wrong or irrelevant answers" long before anyone suspects the vector layer.

  • Mismatched embedding models: embedding stored data with one model and queries with another (or after a silent version bump) breaks the geometry, so results look random until you re-embed everything with one consistent model.
  • Chunks that are too big or too small: oversized chunks blur meaning and waste the context window, while tiny chunks strip away the context that made a passage useful, both tanking answer quality.
  • Skipping metadata and filters: without tenant, permission, and date fields, similarity search will happily return another customer's data or stale content, which is a quality bug and a security problem at once.
  • Treating recall as free: ANN trades a little accuracy for speed, and if you never measure recall against an exact baseline you will not notice the day a parameter change drops it from 98 to 85 percent.
  • Pure vector search with no keyword fallback: semantic search misses exact tokens like order numbers, SKUs, and error codes, so add hybrid (keyword plus vector) search when precise terms matter.
  • Forgetting freshness: if you never update or delete vectors when source documents change, the system keeps confidently retrieving content you already removed.

A practical decision framework

Start with the simplest thing that could work and only add complexity when a real constraint forces it. The order below keeps you from over-engineering on day one and from getting stuck on day two hundred.

First, pick one embedding model and write its name and version down, because that choice touches everything downstream and changing it later means re-embedding your whole corpus. Second, chunk on natural structure (headings, sections, functions) at a few hundred tokens with small overlap, and attach rich metadata to every chunk from the start, including tenant and permission tags. Third, store in pgvector with an HNSW index unless you already know you are past tens of millions of vectors. Fourth, measure recall and latency on a real sample, tune the index knobs, and add hybrid search if exact terms matter for your domain.

Only after all of that, if you hit a named wall (latency at scale, rebuild times, filtered search at one hundred million vectors), graduate to a dedicated vector database. Most teams never need to, and the ones that do will know exactly why. The goal is meaning-aware retrieval that is fast, scoped to the right data, and cheap to operate, not the most impressive infrastructure diagram.

Frequently asked questions

What is the difference between embeddings and a vector database?

+

An embedding is the data: a list of numbers that captures the meaning of a piece of text, image, or other input. A vector database is the system that stores those embeddings, indexes them for fast nearest-neighbor search, and runs that search alongside metadata filters. You need both: embeddings to represent meaning and a vector database to search across millions of them quickly.

Why is cosine similarity used for vector search?

+

Cosine similarity measures the angle between two vectors rather than their straight-line distance, which suits text because the direction of an embedding carries the meaning while its magnitude usually does not. Scores range from about 1 for nearly identical meaning down to -1 for opposite meaning. When vectors are normalized to unit length, cosine similarity and dot product give the same ranking, and dot product is faster to compute.

What is the difference between HNSW and IVF indexes?

+

HNSW builds a layered graph of vectors and walks it to find nearest neighbors, giving an excellent speed-to-recall tradeoff with no training step, at the cost of higher memory and slower builds. IVF clusters vectors into lists and only searches the lists nearest the query, building faster and using less memory but with a weaker speed-recall tradeoff. HNSW is the default for most production systems in 2026; IVF fits very large, mostly static datasets where memory or build time is the constraint.

Do I need a dedicated vector database or is pgvector enough?

+

For most teams pgvector inside Postgres is enough and handles RAG and agent-memory workloads into the tens of millions of vectors with moderate query volume. It keeps your vectors and relational data in one transactional system, so there is no separate store to sync. Move to a dedicated vector database like Qdrant, Milvus, or Pinecone when you can name a specific bottleneck, such as 50 to 100 million-plus vectors, single-digit-millisecond p99 latency at high QPS, or heavy filtered search at scale.

What is chunking and why does it matter for RAG?

+

Chunking is splitting long documents into smaller passages, typically a few hundred tokens with a small overlap, before embedding them. It matters because embedding an entire long document produces a blurry average of all its topics, while embedding tiny fragments strips away context. Chunking on natural structure like headings or sections keeps related ideas together and directly improves how relevant your retrieved results are.

How do embeddings power retrieval-augmented generation?

+

RAG embeds the user's question, retrieves the most similar chunks from your own content using a vector search, and passes those chunks to a language model as grounding context. This lets the model answer from current, company-specific material instead of relying only on its training data. The result is answers tied to real documents, which reduces hallucinations and lets you cite sources.

What is metadata filtering in a vector database?

+

Metadata filtering means storing structured fields like tenant ID, document type, date, and permission tags next to each vector and applying them during or before the similarity search. It ensures a search returns only vectors the user is allowed to see and that meet the right constraints, such as a single customer's documents from the last 90 days. Without it, semantic search can surface another tenant's data or stale content, which is both a quality and a security problem.

How many dimensions should an embedding have?

+

Common text embedding sizes are 384, 768, and 1,536 dimensions, with higher counts capturing finer distinctions at the cost of more storage and slower search. Pick based on your accuracy needs and budget rather than assuming bigger is always better, since gains shrink past a point. The most important rule is consistency: embed your stored data and your queries with the same model and version so the geometry lines up.

Build AI agents that retrieve, reason, and act

OnPilot agents connect to your data and tools, retrieve the right context, and deliver finished work to Slack, Teams, or your app, with approvals, RBAC, and audit logs built in. Start with the developer docs to embed an agent in minutes.

Read the developer docs