Open source · Python 3.11–3.14View on PyPI

Billion-scale vector search, built on Parquet.

ParqDB is an embedded vector database for larger-than-memory search and analytics, powered by Parquet and Arrow.

$pip install parqdb
QUERY PLAN / IVF-LVQ8 READY
01ROUTEcentroids.parquet64 probes
02PRUNEcid_bucket + row groupbounded I/O
03RANKnative LVQ8 kerneltop k
04JOINsource keys → ParquetArrow
PARQUETARROWDATAFUSIONSIMD
1 billionvectors searched
63.05 msmedian latency
90.3%Recall@10
2 cores · 4 GBquery resource limit

SIFT1B · IVF-LVQ8 · nprobe 32 · exact conditions and raw results are published with the benchmark.

Why ParqDB

The index is data.
The engine stays open.

Vector search should fit into your data system—not force every workload through another proprietary service.

01

Everything is Parquet

Source data and vector indexes use standard Parquet. Version, publish, inspect, and share them with the tools you already use.

Explore the format
02

Scale beyond memory

Explicit cluster, file, row-group, and page pruning keeps search bounded while the index grows far beyond RAM.

Read the benchmarks
03

Search stays relational

Compose vector search with filters, joins, and aggregations in one DataFusion plan, backed by Arrow-native execution.

Build a query
One index, multiple runtimes

Build once. Query where the work happens.

ParqDB separates the open index format from the runtime that executes it.

SOURCEMultimodal tablevectors + payloadPARQUET
BUILD
OPEN INDEXIVF / LVQ4 / LVQ8centroids + postingsPARQUET
EMBEDDEDDataFusionin-process Python
BROWSERWASMHTTP Range
SERVERArrow IPCexperimental
Five-minute start

From Parquet to nearest neighbors.

Install one Python package. Build a persistent IVF index. Keep the result inside the Arrow ecosystem.

  • 01Register an existing Parquet table
  • 02Build a source-keyed vector index
  • 03Filter, rank, and collect as Arrow
Follow the guide
quickstart
import parqdb

session = parqdb.connect("./parqdb-data")
session.register_parquet(
    "documents",
    parqdb.datasets.uri("documents"),
)
documents = session.table("documents")

documents.create_index(
    "documents_embedding",
    column="embedding",
    key=["document_id"],
    config=parqdb.IVF(nlist=3),
)
documents.wait_for_index("documents_embedding")

hits = session.collect(
    documents.search([0.2, 0.0])
    .where("status = 'published'")
    .limit(10)
)
Static HTTP index

Object storage becomes the query endpoint.

Publish an immutable IVF-LVQ index and query only the required Parquet byte ranges in WebAssembly. No query server sits between the browser and your data.

HTTP TRACE LIVE INDEX
RANGEcentroids.parquet0–262143206
HITroots.parquetmemory cacheCACHE
RANGEcid_bucket=0000418630–144983206
RANGEdocuments.parquet17465660–17483301206
Start in process

Keep your vectors in an open format.

Install ParqDB and build your first index from an existing Parquet table.