Skip to content

Namespaces & multi-tenancy

A namespace is the fundamental unit of isolation in NamiDB. Every URI carries a ?ns=… query parameter that names it.

client_a = tg.Client("s3://my-bucket?ns=tenant-acme")
client_b = tg.Client("s3://my-bucket?ns=tenant-globex")

These two clients share nothing at the engine level — different manifests, different SSTs, different WALs, different schema. The only thing they share is your bucket prefix.

What lives at a namespace

  • Schema — labels, property types, indexes
  • Data — every node, edge, property, vector
  • WAL — append-only log segments
  • SSTs — immutable columnar files (Parquet for nodes, custom for edges)
  • Manifest — the CAS root that names everything currently live
  • Epoch — a fencing counter for single-writer enforcement

Single-writer per namespace

Each namespace has one active writer at a time, fenced by epoch CAS. If two processes try to mutate the same namespace, only one commits — the loser sees a 412 Precondition Failed on the manifest PUT, re-reads, and either retries or backs off.

This is what gives you correctness without a consensus tier. It’s also why “more write throughput” means “more namespaces”, not “more writers per namespace”.

Multi-tenancy is namespacing

The canonical NamiDB tenancy model:

s3://my-bucket/data/
├── tenant-acme/ ← one namespace
├── tenant-globex/ ← another
└── tenant-initech/ ← another

Each tenant:

  • Has its own manifest, WAL, SSTs
  • Can be backed up, restored, deleted as a single S3 prefix
  • Scales to zero independently
  • Is fenced from every other tenant

This is the same pattern that’s worked for turbopuffer (vectors) and other object-storage-native systems.

When to make a new namespace

  • New tenant — always.
  • New environment (dev / staging / prod) — usually.
  • Schema divergence — when two parts of your app have unrelated graphs.
  • You want independent backups — namespaces back up cleanly with aws s3 sync.

When NOT to

  • “I want more write throughput on this one workload.” Sharding writes across multiple namespaces only helps if your queries also fit inside one shard. Cross-namespace joins are not a thing in NamiDB.

See also