Skip to content

Tenants

A tenant is Eelden's consistency and isolation boundary. Every query runs against the current tenant. Transactions never cross tenants. Forks and snapshots are O(1) copy-on-write catalog operations over versioned pages.

Why this is not an app-layer tenant_id project: Shift left · Business value.

Catalog operations

In language (parsed; also available via Studio / HTTP /ops):

eel
create tenant "acme"
fork tenant "acme" as "acme-staging"
snapshot tenant "acme" as "pre-launch"
suspend tenant "acme"
delete tenant "acme"
OpEffect
createNew empty tenant in the catalog
forkCopy-on-write child sharing page identities until writes diverge
snapshotNamed point-in-time pin used by asof and Studio time-travel
suspendMark tenant unavailable for normal use
deleteRemove catalog entry (reclaim is queued; protected tenants refuse delete)
compactRewrite live rows for a tenant (eelden compact / /ops)

Default tenant

Opening a database binds default. Studio routes as /#/t/:tenant. HTTP paths are /api/v1/t/:tenant/….

What isolation means today

  • Queries and atomic blocks see one tenant's collections only.
  • CDC tails are per-tenant.
  • Schema fingerprints and lazy migration apply per tenant on touch.
  • across tenants(pred) collection parses but does not execute yet — see Status.

Cross-tenant work

App-layer pattern: emit CDC from each tenant, maintain a read model, coordinate with sagas. The engine will not offer cross-tenant ACID.

Pre-alpha. Local-first. Stdlib-only Rust engine. Tenant concerns shifted left into the database.