Feature deep-dive

Multi-Tenant Vector Database with True Per-Customer Isolation

DBX gives every customer their own directory, WAL, HNSW index, and snapshot lineage. Isolation is structural — not a key prefix you hope nobody forgets.

01

Why Key-Prefix Multi-Tenancy Fails for AI Products

Most vector databases store every customer's embeddings in a single shared index. They separate tenants by prepending a key prefix — acme:, harbor: — to every record. If a developer omits or misconfigures the prefix, one tenant can read another's data. Performance isolation is equally fragile: a large indexing job by Tenant A can starve Tenant B's queries.

For AI products holding customer-specific memory (conversation histories, RAG context, personalization vectors), this risk is unacceptable. You need isolation that is enforced by the database engine, not by the application developer's discipline.

02

How DBX Isolates Each Tenant Structurally

POST /api/provision creates a live, isolated engine for one customer. That engine gets:

  • Its own data directory — files on disk belong to one tenant
  • Its own write-ahead log (WAL) — crash recovery replays only that customer's mutations
  • Its own HNSW vector index — ANN search operates over a single tenant's embeddings
  • Its own snapshot lineage — backups and restores target exactly one customer
  • Process-level state — on Linux strict mode, each tenant runs in a sealed execution domain with Landlock filesystem restrictions

There is no cross-tenant scan. There is no shared keyspace. Provision, back up, restore, and delete operate on exactly one customer.

Provision in seconds

Create an Isolated Tenant Engine

HTTP
curl -X POST http://localhost:8000/api/provision \
  -H "Authorization: Bearer $DBX_TOKEN" \
  -d '{"id": "acme-corp", "name": "Acme Corp"}'

One call creates a fully isolated engine. The tenant is live immediately — ready for KV operations and vector search via authenticated RESP on port 6380.

Lifecycle operations target one tenant

Back Up, Restore, and Delete One Customer at a Time

Backup
# Back up one customer — SHA-256 checksummed archive
curl -X POST http://localhost:8000/api/tenants/backup \
  -H "Authorization: Bearer $DBX_TOKEN" \
  -d '{"id": "acme-corp"}'

# Delete one customer — purge erases the tenant directory
curl -X POST http://localhost:8000/api/tenants/delete \
  -H "Authorization: Bearer $DBX_TOKEN" \
  -d '{"id": "acme-corp", "purge": true}'

Density at scale

100 Tenants Per Node, Cost Scales with Active Tenants

Vectors are stored as 8-bit scalar-quantized (SQ8) rows in an mmap'd file, with asymmetric distance computation at query time. Payload is roughly a quarter of float32. An idle tenant lives in page cache rather than resident RAM — approximately 14–17 MiB RSS per idle worker.

This is what makes hosting many small tenants viable. The metric is cost per active tenant, not the count of tenants you have signed.

Linux strict mode

Isolation Kernel: Process-Level Tenant Seals

On Linux production, a tenant is a sealed execution domain: its own process, a Landlock-restricted view of the filesystem, and Unix sockets that only the orchestrator can open. The WAL, checkpoints, vector ids, and the HNSW graph are encrypted under a per-tenant key derived from DBX_KEK.

Honest limits: SQ8 vector rows stay memory-mapped and unencrypted so idle tenants remain cheap — use fscrypt or LUKS for those. Data in use is plaintext inside the worker. Re-measured density under strict: ~14–17 MiB RSS per idle worker, worst idle GET ~3–12 ms.