---
title: "Do I need a vector database if I use Postgres?"
description: "Often no: pgvector keeps vectors on the same Postgres row. Add Qdrant or LanceDB only for filtered ANN or a lake. Last reviewed October 2026."
url: "https://www.pixeltable.com/learn/do-i-need-a-vector-database-if-i-use-postgres"
updated: "2026-10-28"
vertical: "Retrieval"
doc: "https://docs.pixeltable.com/datastore/embedding-index"
---

# Do I need a vector database if I use Postgres?

You need a separate vector database only if nearest-neighbor search cannot live in Postgres. pgvector stores vectors on the same row and answers similarity in SQL. A dedicated engine is for filtered ANN at scale, or for blobs SQL was not built to serve. Many apps stay on Postgres plus an embed job they already run.

Updated: 2026-10-28
Part of [How does an embedding index differ from a vector database?](https://www.pixeltable.com/learn/embedding-index-vs-vector-database).

## On this page

- [Short answer](https://www.pixeltable.com/learn/do-i-need-a-vector-database-if-i-use-postgres#direct-answer)
- [What pgvector actually is](https://www.pixeltable.com/learn/do-i-need-a-vector-database-if-i-use-postgres#pgvector)
- [When a dedicated vector database still wins](https://www.pixeltable.com/learn/do-i-need-a-vector-database-if-i-use-postgres#when-a-vector-db)
- [How to choose](https://www.pixeltable.com/learn/do-i-need-a-vector-database-if-i-use-postgres#how-to-choose)
- [Last reviewed](https://www.pixeltable.com/learn/do-i-need-a-vector-database-if-i-use-postgres#review)
- [Comparison](https://www.pixeltable.com/learn/do-i-need-a-vector-database-if-i-use-postgres#comparison)
- [Where Pixeltable fits](https://www.pixeltable.com/learn/do-i-need-a-vector-database-if-i-use-postgres#where-pixeltable-fits)
- [Questions](https://www.pixeltable.com/learn/do-i-need-a-vector-database-if-i-use-postgres#questions)

## Short answer {#direct-answer}

Usually no. If Postgres already holds the application row, pgvector adds a vector column, exact search, and HNSW or IVFFlat indexes so nearest neighbors are a SQL query. You still compute embeddings in a worker you write, and media bytes usually live in object storage. A second database is optional until that shape breaks.

## What pgvector actually is {#pgvector}

pgvector is open-source vector similarity search for Postgres: a vector type, L2 / inner product / cosine distance, and optional HNSW or IVFFlat indexes. Filters and joins use the rest of the SQL row. Any host that runs the extension (self-managed Postgres, Supabase, Neon, and others) can serve it. It is not a multimodal lake and not a dedicated ANN cluster. Repo: https://github.com/pgvector/pgvector

## When a dedicated vector database still wins {#when-a-vector-db}

A dedicated engine is the better fit when the serving contract is filtered ANN as a service, not SQL next to the row.

- Qdrant when payload indexes on HNSW, dense and sparse vectors, and a Rust engine you can shard are the product. Docs: https://qdrant.tech/documentation/overview/
- LanceDB when images, video, audio, text, and embeddings should share one Lance table, embedded or as a lakehouse. Docs: https://docs.lancedb.com/
- Pinecone, Weaviate, or Milvus when that vendor query API, hybrid BM25 fusion, or a scale-out cluster is already the contract.
- Stay on pgvector when the vector count and QPS fit one Postgres instance and SQL joins are how you filter.

## How to choose {#how-to-choose}

Start from the system of record, not from a latency bake-off this page did not run.

- If the source of truth is a Postgres row, try pgvector first.
- If the source of truth is a Lance table or a dedicated ANN service, pick that engine and keep Postgres for the parts that are SQL.
- If the source of truth is the passage, frame, or file, declare the index on that table so insert keeps it current. That is not pgvector and not a second database.

## Last reviewed {#review}

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.

## Postgres versus a vector database (last reviewed: Oct 2026) {#comparison}

| Approach | Where vectors live | Filters | When it is enough |
| --- | --- | --- | --- |
| Postgres only | Nowhere; you have no ANN | SQL on scalars | No similarity search needed |
| Postgres plus pgvector | A vector column on the same row | SQL WHERE plus distance | The row is already in Postgres and one instance holds the vectors |
| Dedicated vector DB (Qdrant, Pinecone, Weaviate, Milvus) | Points or objects in that engine | Payload or metadata filters on the ANN graph | Filtered ANN, sharding, or a vendor query SLA is the contract |
| LanceDB | The same Lance table as blobs and features | SQL-style filters, FTS, hybrid (vendor docs) | Multimodal lake layout is the product |
| Index on the source table | On the passage, frame, or file row | where() on that table plus similarity() | Insert should embed and the media is typed columns, not a SQL row you already have |

## Where Pixeltable fits {#where-pixeltable-fits}

Use Pixeltable when the system of record is the passage, frame, or file, not a Postgres row you already join: declare pxt.EmbeddingIndex, query with column.similarity(string=...), and insert keeps the index current. Pixeltable is not pgvector and not a drop-in Qdrant cluster. Keep pgvector when Postgres already holds the row and you will embed in a worker you write. Keep Qdrant, Pinecone, Weaviate, or Milvus when that engine is the serving contract. Keep LanceDB when Lance layout is the product. A product list is pgvector vs Qdrant vs LanceDB.

```python
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 {#questions}

### Is pgvector a vector database? {#faq-1}

It is a Postgres extension that stores vectors and answers nearest-neighbor queries. It is not a separate database process. Teams still call the wider category "a vector database" in conversation; the ops story is Postgres.

### When is pgvector not enough? {#faq-2}

When you need a dedicated ANN service with payload filters and sharding, hybrid BM25 fusion as the product, or multimodal blobs in a Lance table. Official pgvector scope is SQL next to the row: https://github.com/pgvector/pgvector

### Does Postgres store the video files? {#faq-3}

Usually no. pgvector stores vectors. Bytes typically live in object storage with a URL or id on the SQL row. A typed Video column is a different schema.

### Do I still have to embed myself? {#faq-4}

Yes for pgvector. Dedicated engines also need embeddings unless you add their inference product. An EmbeddingIndex on a source table embeds on insert as part of the schema.

## Related

- [Embedding index vs a vector database](https://www.pixeltable.com/learn/embedding-index-vs-vector-database)
- [pgvector vs Qdrant vs LanceDB](https://www.pixeltable.com/learn/pgvector-vs-qdrant-vs-lancedb)
- [Best Pinecone alternatives](https://www.pixeltable.com/learn/best-pinecone-alternatives)
- [Vector database alternatives for multimodal apps](https://www.pixeltable.com/learn/vector-database-alternatives-for-multimodal-apps)
- [Pixeltable vs Supabase](https://www.pixeltable.com/compare/pixeltable-vs-supabase)
- [Pixeltable vs Pinecone](https://www.pixeltable.com/compare/pixeltable-vs-pinecone)
- [Embedding index docs](https://docs.pixeltable.com/datastore/embedding-index)
- [pgvector](https://github.com/pgvector/pgvector)
