PAVEDB

RETRIEVAL YOU CAN OWN

Retrieval you can inspect. Infrastructure you can own.

Run PaveDB locally or over HTTP. Text search keeps its source, query record, and replay trail.

Quick start

Python · embedded

pip install pavedb

from pavesdk.client import connect

db = connect("./data")  # in-process; no server, no config
books = db.create_collection("books")
books.add("Captain Nemo commands the Nautilus.", docid="note-1")
hits = books.search("submarine captain", k=3)

Searching in seconds, no server to run.

When you deploy a core, the same connect() takes a URL.

Start building →

Grow with your app

One engine and one interface from first prototype to production — your code barely changes. No throwaway prototype stack, no forced move to a hosted service mid-project.

  1. Prototype connect() Ephemeral store in a temp directory; nothing left behind.
  2. Persist connect("./data") Point at a directory. Same code, now durable.
  3. Serve pavesrv --data-dir ./data The same directory over HTTP — staging speaks the production wire protocol.
  4. Deploy docker run … pavedb:latest-cpu The prebuilt image on your server; clients switch with one line.
  5. Migrate pavecli dump-archive Snapshot every tenant and collection, restore it into the remote instance.

Managed hosting · a FLOWLEXI. service

Or skip the last step

Self-hosting is the whole story above: the image, the CLI, and the archive are yours, and PaveDB stays open source. When running the instance is not the part you want to own, Flowlexi Cloud runs it for you — same engine, same API, same archive format. You keep the keys, the archive, and the exit.

Explore PaveDB Cloud →

Inspect, explain, replay

Python
from pavesdk.client import connect

db = connect("./data")
books = db.create_collection("books")
books.add("Captain Nemo commands the Nautilus.", docid="note-1")

# Search, then inspect the stored request and replay it.
hits = books.search("submarine captain", k=3)
query = books.queries(limit=1)[0]
record = books.get_query(query["query_id"])
again = books.replay(query["query_id"])
Elixir
client =
  PaveDBClient.connect("http://localhost:8086",
    tenant: "tenant",
    api_key: "secret"
  )

{:ok, books} =
  PaveDBClient.create_collection(client, "books", display_name: "Books")

{:ok, _doc} =
  PaveDBClient.Collection.add(books, "Captain Nemo commands the Nautilus.",
    docid: "note-1",
    metadata: %{"kind" => "note"}
  )

{:ok, response} =
  PaveDBClient.Collection.search(books, "captain", k: 3)

matches = response["matches"]

Build an app

Pick a client, then point it at a PaveDB core you run — installed directly or in Docker.

Choose your path →

Why PaveDB

Ingest files, not embeddings

Hand PaveDB a PDF, CSV, or TXT file; it chunks, embeds, and indexes the content without a separate preprocessing pipeline.

Full provenance on text-backed hits

Trace a match to its document, page or character offset, and exact snippet. Vector-only records may not carry text.

Inspect and replay text queries

Retrieve stored parameters, timing, results, and provenance, then replay by query ID. Raw-vector searches are not replayable.

Multi-tenant by default

Tenant and collection namespacing are built in and stay out of the way when one tenant is enough.

Embed it, script it, or serve it

Use local or remote Python, the CLI, or the documented HTTP/OpenAPI surface.

Pluggable embeddings

Choose a shipped local or hosted embedding backend and model per collection.

The book

Inspectable Retrieval with PaveDB

Building RAG and semantic search systems you can deploy, operate, observe, and trust.

Read the book →
Ready to build? Start building →