Skip to main content
Applies to: Embedded ❌, Enterprise ✅ RTE Read covers what a query against an RTE-enabled table returns: base-table rows merged with the fresh tier, fresh rows superseding base rows with the same primary key. On a single Embedded process that merge is one function call against one Lance dataset. In LanceDB Enterprise, the base table and the fresh tier are usually served by different machines — plan executors for the base table, an RTE node for the table’s shards — so a query has to combine their results across the network instead.

An extra exec node, not a parallel system

The distributed plan for an RTE-enabled table is an ordinary plan executor query plan with one additional node spliced in: a union exec that queries the owning RTE node’s shard and merges its rows into the base arm’s stream by primary key, keeping the newest generation on a collision and cutting back to the requested top-K once both sides have contributed. An optimizer pass inserts this node only when the query actually touches an RTE-enabled table; a query that touches none produces a plan identical to one with no RTE tables involved at all, so RTE adds no overhead to queries that never use it. Because the base arm already read through the plan-executor fleet’s ordinary caches and index structures, the only new network hop this adds is the one to the RTE node that owns the table’s shards — the same RTE node Real Time writes land on, found by the query node through the same consistent hash of database and table name.

Search stays index-covered

Every tier the union exec reads from — the base table, the RTE node’s SSTables, and its currently-active memtable — is covered by a maintained index, for vector, full-text, and scalar search alike:
For full-text and scalar search, a maintained index covers every tier the union exec reads from — the base table, the RTE node’s SSTables, and its currently-active memtable — so a row written a moment ago is just as index-searchable as one written yesterday. If a resident memtable predates an index being added to the maintained set, the query is rejected outright rather than silently missing that memtable’s rows; there is no code path that quietly returns an incomplete result. Vector (ANN) search follows the same rule for the base table and SSTables. The active memtable’s rows are ANN-searchable too: it builds its own in-memory HNSW graph as rows land, so writes stay vector-searchable within milliseconds without waiting for a freeze into an SSTable. * That graph search steps aside for a full scan of the memtable only when it can’t honor the query correctly through a graph: a prefilter predicate (graph traversal can’t apply an arbitrary filter first), a primary-key override that could let a stale near vector occupy a top-K slot a newer row should have, a distance lower bound (only a full scan can exclude the nearest rows before the top-K cut), or before the memtable has any index yet on a cold start. Outside those cases, every committed row — base table, SSTables, and the active memtable alike — is covered by a real index, with no sliver of unindexed data left to scan in full. Both guarantees depend on the table’s RTE write spec actually maintaining the index in question — by default every index is maintained, but a deployment that pins a smaller set with with_maintained_indexes loses the guarantee for whatever it leaves out, and a query against an unmaintained index is rejected the same way, rather than silently searching the base table alone.

What to read next

RTE Read

What a query returns, and how Embedded does this same merge in-process.

Distributed RTE Write

How writes reach the RTE node this page’s queries read from.

Distributed Search

The ordinary plan-executor path this layers on top of.