Database per tenant
Give each customer their own database. Their data stays separate, and removing a customer is just deleting their database.
The tutorial builds this step by step.
Give a Worker a group
Section titled “Give a Worker a group”const tenants = yield* Turso.ManageDatabases(Tenants);Add Turso.ManageDatabasesHttp to the Worker. The Worker gets two tokens:
- An API token that can create and delete databases, but only in
Tenants. - A database token that can run SQL on every database in
Tenants.
Your own Turso API token stays on your machine.
Create a tenant
Section titled “Create a tenant”const acme = yield* tenants.create("acme");Names must be unique in your organization. Add a prefix if several stages or apps share it.
Start every tenant from a template
Section titled “Start every tenant from a template”const acme = yield* tenants.create("acme", { seed: { type: "database", name: yield* templateName },});Copy a template database so new tenants start with your tables. See Create the template database.
Query a tenant
Section titled “Query a tenant”const sql = yield* SQL.LibSQL(tenants.connect("acme"));const notes = yield* sql`SELECT * FROM notes`;connect works with Drizzle.LibSQL too. The connection opens on the first query and closes when the request ends.
List and delete tenants
Section titled “List and delete tenants”const all = yield* tenants.list();const acme = yield* tenants.get("acme"); // undefined when missingyield* tenants.delete("acme");delete doesn’t fail if the database is already gone.
Update existing tenants
Section titled “Update existing tenants”New migrations run on the template, not on tenants you already created.
If you know your tenants ahead of time, create each one in the Stack so every deploy updates it:
for (const name of ["acme", "globex"]) { yield* Turso.Database(name, { name, group: group.name, migrations: "./migrations" });}For tenants your app creates, run the change on each one from the Worker. Write it so running it twice is safe:
for (const { name } of yield* tenants.list()) { const sql = yield* SQL.LibSQL(tenants.connect(name)); yield* sql`CREATE INDEX IF NOT EXISTS notes_created ON notes (created_at)`;}Destroying the Stack
Section titled “Destroying the Stack”Destroying the Stack deletes the group and every tenant database in it.