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.

Run it in five minutesopen source · Apache-2.0 · signed build coming
the instrument

Every read, with what it cost

Six operations on the reference corpus — 1,114 moments and 162 segments across 16 talks. The rail is logarithmic, because at this scale a proportional bar renders as nothing at all. Zero is not plotted: an operation that reads no video prints NONE rather than a bar of length zero, which would look like a small amount.
semantic search over every moment
1 / 6
the rail runs from 1 KB to the whole corpus, 2.65 GB
index3.45 MB
video
NONE
bytes an index readbytes of video read

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.

the ratio

132 to 1

The same fact as area, for anyone who would rather glance than read.

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.

two true numbers

The manifest and the disk disagree, correctly

This is a limitation of the format's own bookkeeping, and it is on the landing page because it is the reason the tool exists.
43,424 bytes
what the manifest reports

Lance's own tracked_files(), asked how big this table is.

2.65 GB
what is actually on disk

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.

someone else's data

The same claim, on a dataset this project did not build

Point a fresh install at a public Hugging Face dataset and watch the counter. Nothing is downloaded — the URI is saved, not the corpus.
937,957
rows

each carrying an MP4 beside its embedding

24,568 bytes
to open it

two IO operations, over the network, in under a second

about 73 KB
to browse five rows

and no video at all

urihf://datasets/lance-format/openvid-lance/data

Re-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.

what it does

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.

the write boundary

What it will and will not touch

It will build you a database. It will never edit one.

browsing

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.

building

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.

for agents

Point a model at it

The same read-only surface over MCP, so an agent gets evidence instead of guesses.
mcpclaude mcp add lancescope -- uv --directory /path/to/lancescope run python -m server.mcp_server
list_tablesdescribe_tableread_rowstable_findingstable_fragmentstable_indicestable_versions

Seven 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.

also included
the demo it grew out of

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.

get it

Runs on your machine, against your data

no signed build published yet

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.

1git clone https://github.com/mrlynn/lancescope && cd lancescope
2make setup
3make dev

Then 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.

appmake app

A 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.