Map

AI Engineer Track · Embeddings Vector Dbs

Vector Databases & Indexes

Core~20 min

Vector Databases & Indexes

A vector database stores embeddings and answers 'what is most similar to this' queries quickly, usually while also letting you filter by structured fields like date or category. Options range from lightweight in-process libraries to purpose-built engines, fully managed cloud services, and extensions bolted onto an existing database like Postgres, differing mainly in scale, filtering power, and how much operational effort they demand.

Why this matters

At small scale, almost any of these choices works fine; at real scale, the differences that actually decide whether a system holds up, filtering, multi-customer isolation, operational maturity, become the whole story. Picking a database by hype rather than by actual filtering and scale needs is a common and expensive mistake.

What a vector database record actually stores

A commonly overlooked detail is that a vector database does not store only vectors. Every record is really a bundle of three things: the vector itself, used purely for nearest-neighbor search; the original text, which is what you actually want returned; and metadata, used for filtering on fields like tenant, date, document type, or permissions. Search only ever compares against the vector field, but what comes back is the whole record, so 'the chunk' is really just reading the text field off that returned record. This matters because it clears up the most common confusion about retrieval: asking for the top-k chunks returns k full records, and the text is pulled off each one and assembled into the prompt afterward. Since the text has to be stored somewhere, some systems, Pinecone among them, have no separate text column and expect the text to be placed directly inside the metadata, while others, pgvector and Chroma, provide an explicit text column; the underlying pattern is identical, only the syntax differs between them.

A vector database is a search index where the query is 'find records whose vectors are closest to this point, optionally restricted by these filters,' and the result is records, not bare vectors.

pgvector, Pinecone, and Chroma in practice

Three widely used vector databases all implement the same three concepts, vector plus text plus metadata, filtering on metadata, searching on the vector, in slightly different API dialects. pgvector is a Postgres extension, which means a team already running Postgres gets vector search without introducing a second database system to keep in sync; its distance operator has to be chosen to match how the embedding model was trained, and metadata filters applied in the same query run before the vector comparison, which is exactly what makes multi-tenant isolation safe. Pinecone is fully managed with no server to run, storing the text directly inside the metadata dictionary since it has no separate text column, making the 'record bundles vector, text, and metadata' idea completely literal in its API. Chroma runs in-process with essentially zero setup, which makes it well suited to prototyping rather than large-scale production use. Learning any one of the three transfers almost entirely to the others, since the underlying concepts never change, only the vocabulary does.

pgvector, Pinecone, and Chroma are the same three ideas wearing different API syntax. Learn the concepts once and each specific database becomes a quick reference lookup.

Metadata filtering and multi-tenant isolation

Metadata filtering is what turns a vector database from a toy into something safe to run in production, because it is the actual security and correctness boundary in any multi-tenant system. The underlying problem is that embedding similarity has no concept of ownership at all: a search for how to reset a password can return a different customer's internal runbook purely because the two are semantically similar, unless a filter restricts the search to the right customer's documents in the first place. Two filtering patterns exist, each with a real tradeoff. Pre-filtering narrows the candidate set before running the vector search, which is safe but can starve an approximate index of enough neighbors to search when the filter is very selective, hurting recall. Post-filtering searches broadly first and drops unauthorized results afterward, preserving recall but sometimes returning fewer than the requested number of results once unauthorized hits are removed. The rule that matters more than which pattern is chosen is that the permission filter has to run as part of the query itself, never afterward in application code, because retrieving broadly and checking permissions only after the fact means an unauthorized document has already entered the context sent to the model, and the leak has already happened by the time the check runs. The test worth writing is a negative one: proving directly that a user scoped to one tenant cannot retrieve a document belonging to another.

The permission filter has to be part of the vector query itself, not a check applied afterward in application code, and a negative test proving cross-tenant isolation is what actually proves the filtering works.

Worked example

A multi-tenant support-ticket search system that filters by client_id as part of the vector query itself correctly returns only that client's tickets even when another client's tickets are semantically closer to the query, while the same system filtering in application code after a broad retrieval would have already exposed the other client's ticket content to the model before the filter ever ran.

Practice

Load a thousand documents into two vector databases, for example Chroma and pgvector, and run the same filtered queries against both. Confirm equivalent results, and write a comparison of when you would choose each one in production based on scale, operations, filtering, and existing infrastructure.

Interview checks

  • Why is it unsafe to filter for permissions in application code after retrieval instead of inside the query itself?
  • What is actually stored alongside the vector in a typical vector database record?
  • What is the practical tradeoff between pre-filtering and post-filtering?

Common failure modes

  • Choosing a vector database based on hype before knowing your actual scale and filtering requirements.
  • Ignoring metadata filtering capabilities, which is often the single most important requirement for enterprise use.
  • Using an in-memory store in production and losing the entire index on a restart.
  • Underestimating how much tuning an HNSW index's construction and search parameters actually requires to hit a target recall.

Resources

  • FAISS — The library that defined modern vector search; its README and wiki lay out the index taxonomy of flat, IVF, and HNSW approaches.
  • pgvector — Vector search inside Postgres, representing the 'vectors next to your relational data' architecture many enterprises prefer.
  • Pinecone docs — The managed-service reference; its concepts pages describe the production architecture of a hosted vector database.

Expert signals

Choosing a vector database from actual filtering, scale, and operational requirements, recognizing that pgvector's 'vectors next to your data' model is the enterprise default for teams already on Postgres, and tuning approximate-index parameters deliberately rather than leaving them at their defaults, is what separates a production-ready vector search setup from one that merely works in a demo.

Confidence

high