Retrieval

pgvector vs Qdrant vs LanceDB

pgvector, Qdrant, and LanceDB are three ways to store vectors and search nearest neighbors. pgvector is a PostgreSQL extension. Qdrant is a dedicated vector search engine. LanceDB is a multimodal lake plus ANN on the Lance format. They differ on where the rest of the row lives, how you filter, and whether media bytes sit in the same table.

Updated · Part of What is an embedding index?

Three vector stores

All three answer nearest-neighbor queries. The split is the rest of the application: SQL joins, payload filters on a dedicated engine, or blobs in a Lance table.

pgvector

pgvector is open-source vector similarity search for Postgres: vector columns, exact search, and HNSW or IVFFlat indexes, with SQL joins and filters on the rest of the row. Any host that runs the extension (self-managed Postgres, Supabase, Neon, and others) can serve it. Media usually lives in object storage you add. Repo: https://github.com/pgvector/pgvector

Qdrant

Qdrant is an open-source vector search engine written in Rust. Collections hold points: vectors plus payload. Payload indexes extend the HNSW graph so filters apply during search. It supports dense and sparse vectors, BM25 on a text field, and deployments from OSS to Qdrant Cloud, Hybrid Cloud, and Private Cloud. Docs: https://qdrant.tech/documentation/overview/

LanceDB

LanceDB stores images, video, audio, text, embeddings, and features in one Lance table and serves vector search, full-text search, hybrid search, reranking, filtering, and SQL. OSS is an embedded library. Enterprise is a distributed lakehouse. Docs: https://docs.lancedb.com/

How to choose

Start from the system of record you already run.

  • Pick pgvector when Postgres already holds the application row and SQL is how you join and filter.
  • Pick Qdrant when a dedicated ANN service with rich payload filters is the serving contract.
  • Pick LanceDB when multimodal blobs and vectors should share one Lance table, embedded or as a lakehouse.

Last reviewed

Facts on this page were checked against vendor documentation on 2026-10-28. Product surfaces move; treat version names and APIs as directional and follow the official links in Related.

pgvector vs Qdrant vs LanceDB (last reviewed: Oct 2026)

pgvector vs Qdrant vs LanceDB (last reviewed: Oct 2026)
pgvectorQdrantLanceDB
What it isPostgres extension for vector columnsDedicated vector search engine (Rust)Multimodal lake plus ANN on Lance
Where the rest of the row livesThe same Postgres rowPayload on the point; files usually elsewhereThe same Lance table (blobs, features, vectors)
FiltersSQL WHEREPayload indexes on HNSW; sparse and BM25 optionsSQL-style filters, FTS, hybrid, rerank (vendor docs)
OpsWhatever already runs PostgresOSS server or Qdrant Cloud / Hybrid / PrivateEmbedded OSS process, or Enterprise
Best forTeams already on PostgresFiltered ANN as a separate serviceLake layout and embedded or lake-scale retrieval
Official docshttps://github.com/pgvector/pgvectorhttps://qdrant.tech/documentation/overview/https://docs.lancedb.com/

Where Pixeltable fits

Use Pixeltable when the index should be declared on the table that holds the passage or frame, so insert and delete keep it current, and typed media can sit on the same schema. Pixeltable is not a drop-in Qdrant cluster and not a Lance lakehouse. Keep pgvector when Postgres is already the system of record and you will embed in a worker you write. Keep Qdrant when that engine is the serving contract. Keep LanceDB when Lance layout is the product; export with pxt.io.export_lancedb when you want that engine.

import pixeltable as pxt
from pixeltable.functions.huggingface import sentence_transformer
TableModel = pxt.model_base()
embed = sentence_transformer.using(
model_id='sentence-transformers/all-MiniLM-L6-v2'
)
class Passages(TableModel, name='passages'):
text: pxt.String
source: pxt.String
__indexes__ = [
pxt.EmbeddingIndex(text, string_embed=embed),
]
@pxt.query
def search_passages(query: str, limit: int = 5):
sim = Passages.text.similarity(string=query)
return (
Passages.order_by(sim, asc=False)
.limit(limit)
.select(Passages.text, Passages.source, sim)
)

Questions

Is pgvector enough instead of Qdrant?

Often, if Postgres already holds the row and the vector count and QPS fit one Postgres instance. Qdrant is the better fit when filtered ANN, sharding, and a dedicated engine are the contract.

Does LanceDB replace pgvector?

Only if you move the serving index onto Lance tables. pgvector stays when SQL joins on Postgres rows are the product. LanceDB stays when blobs and vectors share a Lance table.

Where do the video files live?

With pgvector and Qdrant, usually in object storage, with a URL or id in payload or SQL. With LanceDB, as blob columns in the Lance table (or external URIs). With an application schema, as a typed Video column.

Do I still need to embed myself?

Yes for pgvector and typically for Qdrant and LanceDB unless you add their embedding functions or an integrated inference product. An EmbeddingIndex on a source table embeds on insert as part of the schema.

Next step

Install the Pixeltable skill, or sign up for Cloud and run the same file on a hosted database.