A Lance table can hold 2.65 GB of video
while a search over it reads none.
LanceScope is a workbench for reading LanceDB datasets: schema, versions, indices, fragments and rows, with the byte cost of every read shown as you go. The bytes a search touches and the bytes a table holds live in different files. It measures both.
Every read, with what it cost
Re-measured by `make verify` on 2 September 2026, on the 16-talk corpus (1,114 moments, 162 segments): vector search 3.45 MB index and 0 B video, FTS 0.11 MB and 0 B, blob handle 2,722 B, cold segment 17.0 MB, warm seek 262,144 B. The check that asserts search reads zero video bytes passes.
132 to 1
2.65 GB of video in .blob side files, against 20.0 MB of everything a search reads. One square is lit.
Re-measured on the reference corpus, 2 September 2026: 2.651 GB in .blob side files against 20.04 MB for the moments table a search actually reads.
The manifest and the disk disagree, correctly
Lance's own tracked_files(), asked how big this table is.
The same table, measured by walking it.
tracked_files() lists no .blob paths, so the manifest cannot see the side files where the video lives. Neither number is wrong; they answer different questions, and which one you want depends on whether you are asking what a query will cost or what the storage bill will say. LanceScope shows both, and says which is which.
docs/guide/explain-blobs.md. Lance says the same thing in its own API documentation — “Blob v2 payloads live in separate blob files and are not counted” (lance/optimize.py) — so this is the format behaving as designed, not a defect.
The same claim, on a dataset this project did not build
each carrying an MP4 beside its embedding
two IO operations, over the network, in under a second
and no video at all
hf://datasets/lance-format/openvid-lance/dataRe-opened over the network on 2 September 2026: 937,957 rows, 24,568 bytes and 2 IO operations to open, in about a third of a second — counting the rows then cost nothing further. The row count matches LanceDB's own page for the dataset (docs.lancedb.com/datasets/openvid), which also states that the MP4 bytes live in a side blob file that search and filtering never read.
Four things, precisely
Reads a database, exactly
Schema, versions, indices, fragments and rows, with the byte cost of each read shown as you go. Describing 2.65 GB of video costs 23.8 KB and opens none of it.
Answers “why is this slow”
Run a scalar, full-text, vector or hybrid search, see which access path Lance chose, what it read, and the script that reproduces it elsewhere. Compare two versions of a table and run the same query against both.
Says what it already knows
Nine rules over metadata — an unindexed vector column, small-file counts that would be misleading to act on, tombstone debt, a manifest that understates the size of the thing it describes — each carrying the numbers it was derived from. No model is involved in any of them.
Adds language, optionally
With a local model or an API key it will translate a question into a filter and describe a table in a few sentences. Every response reports the tokens and dollars it spent beside the bytes it read.
What it will and will not touch
It will build you a database. It will never edit one.
Reading a table cannot change it. That is checked rather than asserted: a test drives the entire read API and every MCP tool over a real corpus and then checks that not one byte on disk moved.
The ingest wizard creates a new table from your own files, and that is the only thing in the project that writes one. It is create-only by construction: it refuses a destination that already exists, only ever appends into a table it made itself during that same run, and has no reachable path to an overwrite.
The whole write surface is one module, and CI fails if a dataset mutation appears anywhere else. Deleting only ever happens when you ask for it: the button that clears a finished job from the list and the button that deletes the table it produced are deliberately two different buttons.
Point a model at it
claude mcp add lancescope -- uv --directory /path/to/lancescope run python -m server.mcp_serverSeven tools, every one of them read-only and declared as such. Ask it what is in a database and what is wrong with it, and it comes back with the unindexed vector column and what a search therefore costs — with the numbers those conclusions were derived from, not a summary of them.
Ctrl-F for Video
Multimodal search over conference talks, where the video and its index are the same table. Searching the whole corpus reads zero bytes of video — not very little, zero.
It needs a built corpus and a local embedding model, so it is not in the packaged app: the DMG deliberately ships without torch, and the demo screen says so rather than failing quietly. Build it from the repo to run it.
Runs on your machine, against your data
Run it from source — about five minutes
The macOS app is a packaging of the same console you can run directly. Until it is signed, notarised and published, this is the whole thing, and nothing is missing from it.
git clone https://github.com/mrlynn/lancescope && cd lancescopemake setupmake devThen open localhost:3000/console and point it at any directory holding .lance tables — or paste the OpenVid URI above and read someone else’s, over the network, without downloading it. Needs uv and Node.
To build the macOS app yourself — a window that starts and stops its own server, with nothing to install afterwards. Additionally needs Rust.
make appA signed, notarised DMG is the next thing to ship. It is built by a tagged release workflow rather than by hand, so when it lands it will be reproducible and the button above this will change to point at it.