DocumentsLanceDB's Space
Namespace Layer Architecture
Namespace Layer Architecture
Type
Topic
Status
Published
Created
Jul 8, 2026
Updated
Jul 8, 2026

Namespace Layer Architecture#

LanceDB's namespace layer is the subsystem responsible for managing table metadata, discovery, and location resolution. It sits between the Connection API and the physical Lance datasets, and can operate in two modes: directory-listing (default) or manifest-enabled. Both ultimately delegate to LanceNamespaceDatabase, which wraps a LanceNamespace trait object from the external lance_namespace_impls crate.


Connection Routing#

The routing decision happens in ConnectBuilder::execute():

The manifest_enabled flag lives on ConnectRequest and is set via ConnectBuilder::manifest_enabled().

ConnectBuilder::execute()
  ├── db:// URI → RemoteDatabase
  ├── manifest_enabled=true → connect_manifest_enabled_namespace_database()
  │ └── LanceNamespaceDatabase ("dir" impl)
  └── default → connect_with_options()
                   └── ListingDatabase
                        └── [embedded] LanceNamespaceDatabase (for child namespaces)

For direct namespace connections (bypassing the URI-based path entirely), use connect_namespace(ns_impl, properties), which produces a ConnectNamespaceBuilder that calls LanceNamespaceDatabase::connect() directly.


Initialization Path#

Standard mode#

ListingDatabase::connect_namespace_database() is called during ListingDatabase construction to create the embedded namespace database. It:

  1. Builds namespace client properties via build_namespace_client_properties(), setting root to the URI and prefixing storage options with storage.
  2. Calls LanceNamespaceDatabase::connect("dir", ...), which instantiates a ConnectBuilder from lance_namespace_impls

Manifest-enabled mode#

connect_manifest_enabled_namespace_database() additionally injects two properties before connecting :

  • manifest_enabled = "true" — makes the namespace the source of truth for table metadata
  • dir_listing_to_manifest_migration_enabled = "true" — automatically migrates existing directory-listed tables into the manifest on first access

URI restrictions apply: schemes containing + (e.g. s3+ddb://), engine query parameters, and mirroredStore are rejected because they conflict with manifest-based commit management .

Delegation to lance_namespace_impls::ConnectBuilder#

Inside LanceNamespaceDatabase::connect_with_new_table_config() :

  1. Creates lance_namespace_impls::ConnectBuilder::new(ns_impl)
  2. Iterates over ns_properties and calls .property(key, value) for each
  3. Optionally installs a Session via .session()
  4. Installs a ReadFreshnessContextProvider for read consistency
  5. Calls .connect().await to obtain the Arc<dyn LanceNamespace> trait object

The resulting LanceNamespaceDatabase stores the namespace client alongside storage options, read consistency interval, pushdown operation set, and new-table config .


LanceNamespaceDatabase – Core Structure#

LanceNamespaceDatabase implements the Database trait. Its fields:

FieldPurpose
namespace: Arc<dyn LanceNamespace>Delegate for all metadata operations
storage_optionsInherited by all tables
read_consistency_intervalControls read freshness
sessionObject-store registry / cache sharing
pushdown_operationsOperations routed to the namespace server (e.g. QueryTable, CreateTable)
ns_impl / ns_propertiesImpl type (e.g. "dir", "rest") and properties for client reconstruction
new_table_configStorage version, V2 manifest paths, stable row IDs defaults
freshness_baselinesShared baseline map for read-freshness keying
delimiterSeparator for table ID key construction (default "$")

Table operation dispatch:

  • List: namespace.list_tables()
  • Create: namespace.declare_table() → write data → NativeTable::create_from_namespace()
  • Open: NativeTable::open_from_namespace()
  • Drop: namespace.drop_table()
  • Rename: namespace.rename_table()

clone_table is explicitly not supported on namespace connections.


Managed Versioning#

When describe_table or declare_table returns managed_versioning: Some(true), table creation installs ExternalManifestCommitHandler as the Lance commit handler . This routes all version writes through LanceNamespaceExternalManifestStore (from lance::io::commit::namespace_manifest), making the namespace server — not the object store — the version-of-record.

Activated by setting namespace_client_property("table_version_tracking_enabled", "true") on the connection .


Python API#

Python exposes two entry points in namespace.py:

For "dir" and "rest" impls, these call the Rust-native _connect_namespace binding; other impls fall back to constructing a Python LanceNamespace client and passing it to the Rust layer via _connect_namespace_client .


Key Source Files#

FileRole
rust/lancedb/src/connection.rsConnectRequest, ConnectBuilder, connect_namespace(), ConnectNamespaceBuilder
rust/lancedb/src/database/namespace.rsLanceNamespaceDatabase, ExternalManifestCommitHandler wiring
rust/lancedb/src/database/listing.rsListingDatabase, connect_namespace_database(), connect_manifest_enabled_namespace_database()
python/python/lancedb/namespace.pyPython connect_namespace, LanceNamespaceDBConnection, AsyncLanceNamespaceDBConnection
Namespace Layer Architecture | Dosu