Files
lancedb/python
Daniel RammerandClaude Opus 5 d26139417e feat(table): checkpoint_lsm, flush_lsm, compact_lsm, get_lsm_stats
Converge a table's LSM write path into its base table, and inspect it.

`checkpoint_lsm` is `flush` then `compact`, repeated until the fresh tier
is empty — and the loop runs **client-side**. Putting it on the server
would mean a background task, which means a single-flight intent, an
intent that leaks on panic, a bounded-iteration policy, an "is it done"
observable, and a story for every way a client can vanish mid-operation.
None of that exists in this shape: each request does a bounded unit of
work and reports what is left, so completion is *carried in the
responses* rather than inferred from a shared counter that cannot
distinguish "converged" from "hasn't started yet".

Best-effort by construction. Nothing is frozen, so `converged` means L0
was empty as of the last pass. It is idempotent, abandonable at any point
with zero consequence, and safe to run on a cadence — an already-
converged table costs one round trip and zero compaction passes, because
`flush` reports `generations_remaining` and the loop is never entered.

The failure taxonomy is the load-bearing part. Five distinct conditions
used to arrive at a client as one 503, so `Error::LsmRoute` carries a
classification read from the response body's namespace error code *at
the point of receipt* — before any generic helper folds the body into a
string and keeps only the status. Contention (429) retries; a draining
node (503 / `InvalidTableState`) stops, because the drain gate is a
one-way latch and retrying it spins until the deadline to report a
failure that was knowable on the first response. Transport retry is
disabled on these routes for the same reason: it treats every 503 alike.

`get_lsm_stats` returns `Option<LsmStats>`, matching `get_lsm_write_spec`
— `None` only when the table has no LSM write path, since a struct of
zeros would read as measurements.

Python bindings mirror all four, preserving the per-bucket detail rather
than flattening to a table-level summary.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-27 19:38:33 -05:00
..
2025-01-29 08:27:07 -08:00
2024-04-05 16:22:59 -07:00

LanceDB Python SDK

A Python library for LanceDB.

Installation

pip install lancedb

Pre-Haswell x86_64 hosts: lancedb-compat

The default lancedb wheel targets x86-64-haswell (AVX2 + FMA + F16C) for full performance on modern hardware. Pre-Haswell hosts — Intel Sandy Bridge / Ivy Bridge / Westmere; AMD Bulldozer / Piledriver / Steamroller — don't have AVX2 and crash with Illegal instruction at import lancedb.

For those hosts, install the lancedb-compat package instead:

pip install lancedb-compat

Same Python API (import lancedb works as usual). The compat wheel is compiled at the x86-64-v2 baseline (Nehalem-class) and uses runtime SIMD dispatch in the embedded lance crate to pick the right kernel tier (scalar / AVX / AVX+FMA / AVX2+FMA / AVX-512) at load time, so it still goes fast on modern hardware while running cleanly on the pre-Haswell silicon. Use lance.simd_info() from Python to verify which tier was selected.

lancedb and lancedb-compat install to the same lancedb/ namespace and conflict at install time. Pick one. To switch, pip uninstall lancedb first, then pip install lancedb-compat (or vice-versa).

If you need a custom baseline (or lancedb-compat isn't yet published for your platform), build from source with the override:

RUSTFLAGS="-C target-cpu=x86-64-v2" maturin build --release
pip install ./target/wheels/lancedb-*.whl

Preview Releases

Stable releases are created about every 2 weeks. For the latest features and bug fixes, you can install the preview release. These releases receive the same level of testing as stable releases, but are not guaranteed to be available for more than 6 months after they are released. Once your application is stable, we recommend switching to stable releases.

pip install --pre --extra-index-url https://pypi.fury.io/lancedb/ lancedb

Usage

Basic Example

import lancedb
db = lancedb.connect('<PATH_TO_LANCEDB_DATASET>')
table = db.open_table('my_table')
results = table.search([0.1, 0.3]).limit(20).to_list()
print(results)

Development

See CONTRIBUTING.md for information on how to contribute to LanceDB.