Skip to main content
Most B2B SaaS apps are multi-tenant: many customers (workspaces / orgs / accounts) share one application, one database, but never see each other’s data. The pattern:

Schema-level isolation

Every domain table has a workspaceId field. Every query filters by it.
convex/schema.ts

Auth-aware scoping

In every query / mutation that returns workspace data, filter by the active workspace:
The membership check is the gate; the workspace filter is the scope.

URL-scoped routing

Routes include the workspace slug: /w/{slug}/projects, /w/{slug}/settings. The slug → workspaceId resolution happens in a layout component.

Per-tenant limits

For “free tier max 3 projects”:

Common patterns

Workspaces + memberships

Standard. A user can belong to many workspaces. See the Multi-tenant SaaS recipe.

Personal + team workspaces

Each new user gets a personal workspace; can create / join shared ones later.

Subdomain per workspace

acme.yourapp.com, betacorp.yourapp.com. Adds setup complexity but feels premium.

Database-per-tenant (don't)

Common in legacy systems; rarely worth it on Convex. Schema-level isolation is simpler and just as secure.

Multi-tenant SaaS recipe

Full walkthrough.

Roles & permissions

Per-workspace roles.

Data access control

Defending against leaks.
Last modified on April 18, 2026