▣datahall
← back to gallery
embedded-vectorRustest. 2023Apache-2.0

LanceDB

A serverless vector database built on the Lance columnar format: fast scans over multimodal data with embedded ANN indexes.

LanceDB is a serverless vector database whose file format (Lance) is a columnar container optimized for fast random access to large blobs (images, audio, video) plus vector search. It supports embedded use (Node, Python) and a server mode, and ships IVF-PQ and HNSW indexes that live inside the same file as the data.

Storage
Lance columnar
Indexes
IVF-PQ, HNSW
Embedded + Server
Node, Python, Rust
Best for
multimodal RAG

Lance columnar format

A row group per fragment, column-major storage inside each group, plus a row index for fast point lookups. Fragments can be added cheaply and the file is append-friendly.

Vector indexes inside the file

IVF-PQ and HNSW indexes are stored as part of the dataset. Queries run against the index without unpacking the full column.

Serverless or server

The same Rust core runs in-process (no socket, no daemon) or behind a REST API. Pick based on scale.

Multimodal friendly

Native support for image, audio, and video types via the Arrow ecosystem. Embeddings are just one more column.

The Lance file

A Lance file is a directory of fragments plus metadata. Each fragment has N rows; inside a fragment, columns are stored as Arrow IPC chunks. A separate row index maps primary keys to fragment + offset. The result is a file that supports fast column scans (for vector search) and fast row lookups (for primary-key reads).

Fragments can be added in O(1) and the file stays a single object for the consumer. This makes Lance popular for lakehouse-style data over S3 or local disk.

ANN search

LanceDB ships IVF-PQ (good for very large datasets) and HNSW (better recall). Both are built into the Rust core; queries are dispatched there directly. The query plan is simple: load the index, traverse it, fetch the top-k rows from the column store by their row-id, return.

              import lancedb

db = lancedb.connect("./.lancedb")
tbl = db.create_table("docs", data=rows, mode="overwrite")
tbl.create_index(num_partitions=256, num_sub_vectors=96)  # IVF-PQ

results = (
  tbl.search([0.1, 0.2, 0.3, ...])
    .metric("cosine")
    .limit(10)
    .to_pandas()
)
            

Why serverless wins for many workloads

For RAG over a few million embeddings, the cost of running a separate Qdrant or Milvus cluster is hard to justify. LanceDB runs inside the same Python process as the rest of your pipeline: no socket, no auth, no separate ops surface. You pay for the Rust binary and the file. When you outgrow that, you turn on server mode without changing the data layout.

Diagrams

vector-indexIVF-PQ index: inverted file + product quantizationclick nodes for description
cluster 0 — probed (nearest centroid)cluster 1 — skippedcluster 2 — skippedcluster 3 — skipped20101622

probed 1/4 clusters · scanned 6/24 vectors · skipped 18 · recall 0.50 vs exact · top-4: 10, 17, 13, 2

IVF's coarse quantizer prunes clusters by centroid distance; the tradeoff is visible — vectors in skipped clusters can never appear in the result, so recall is capped by the probe count. Product quantization (the PQ in IVF-PQ) is a separate compression step applied inside each cluster's scan; it is not the partitioning shown here.

Vectors are partitioned into Voronoi cells (IVF), and each vector is compressed via product quantization (PQ) into a few bytes. Queries probe nearby cells and approximate distances via lookup tables.

pipelineANN search pipelineclick nodes for description
query vectorexecutionembedding of thequestionIVF-PQ / HNSWindexin-file indexcandidatesindextop-N nearestrerankexecutionfull vectorsrescoredtop-k rowsstorageread from columnstoremode: ann-search

A query vector is quantized, routed to the nearest IVF cell, and compared against PQ codes in nearby cells; the top-k candidates are re-ranked by exact distance.

pipelineWrite path: append a row -> rewrite columnar fileclick nodes for description
stage 1executionplaceholderstage 2storageplaceholdermode: write

Lance file format uses append-only versioning; a write creates a new chunk, and reads pick the latest version per row.

diagramHNSW layered graphclick nodes for description
Vector index · HNSW layered graph
L2 (top)L1L0 (base)query q

A query enters the top layer, hops across neighbors, and drills down to the densest base layer for the top-k.