Multi-Tenant vs Single-Tenant SaaS Architecture
In a multi-tenant SaaS architecture, all customers share one running application and usually one database, separated by a tenant id in every row; in a single-tenant architecture, each customer gets their own instance, at least their own database and sometimes their own servers. Multi-tenant is cheaper per customer and simpler to upgrade, so it is the right default for most SaaS products. Single-tenant buys stronger isolation, per-customer customization and easier compliance answers, at a higher cost per tenant. Most mature products end up with a mix: a shared tier for most customers and dedicated tenants for the few who pay for it.
#Tenancy is a spectrum, not a switch
"Multi-tenant" and "single-tenant" are endpoints. In practice, you pick a level of sharing for each layer of the stack:
| Model | App servers | Database | Typical name |
|---|---|---|---|
| Shared everything | Shared | Shared tables, tenant_id column | Pool |
| Shared app, separate data | Shared | Schema or database per tenant | Bridge |
| Separate stack per tenant | Per tenant | Per tenant | Silo |
| Mixed tiers | Shared for most, dedicated for some | Shared plus some dedicated | Hybrid |
The interesting decisions are mostly in the data layer, because that is where isolation failures leak customer data and where costs grow with tenant count. For the Postgres patterns in detail (shared tables with RLS, schema per tenant, database per tenant), see multi-tenant Postgres for SaaS. This article is about the architecture-level choice.
#Multi-tenant vs single-tenant compared
| Pool (multi-tenant) | Bridge | Silo (single-tenant) | |
|---|---|---|---|
| Cost per extra tenant | Near zero | Low to medium | Highest |
| Onboarding a tenant | Insert a row | Create a schema or database | Provision a whole stack |
| Isolation | Logical (code, RLS) | Data separated, compute shared | Physical or near-physical |
| Blast radius of a bug | All tenants | Usually one tenant's data, shared app | One tenant |
| Noisy neighbors | Real risk | Compute still shared | None between tenants |
| Upgrades and migrations | Once | Once per tenant database | Once per tenant stack |
| Per-tenant customization | Hard | Some (schema, settings) | Easy |
| Per-tenant backup and restore | Hard (row-level) | Easy | Easy |
| Data residency per tenant | Hard | Possible | Easy |
| Cross-tenant analytics | Easy | Needs aggregation | Needs aggregation |
| Compliance questionnaires | More explaining | Easier | Easiest |
Two rows deserve emphasis.
Upgrades. In a pool, a schema migration runs once. With a thousand tenant databases, it runs a thousand times, and some will fail halfway. You need tooling to apply, track and retry migrations per tenant, and your app must cope with tenants on different schema versions during a rollout.
Restore. In a pool, "restore tenant 42 to yesterday" means extracting their rows from a backup and merging them into a live table shared with everyone else. In a silo, it is a normal restore of one database. If customers ask for this often, it pushes you toward separation.
#Where multi-tenant wins
- Unit economics. A free or low-priced plan only works if a new customer costs almost nothing. Pooling makes that possible.
- Speed of iteration. One deployment, one schema, one set of dashboards. Small teams ship faster.
- Product analytics and cross-tenant features. Benchmarks, marketplaces, shared templates and global search are simple queries.
- Even resource use. Many small tenants smooth each other out; you size for the aggregate, not the sum of peaks.
The main risk is isolation by code. Every query must filter by tenant, every time. The fix is to make the database enforce it: Row Level Security policies that check membership, so a forgotten where tenant_id = ... returns nothing instead of another customer's data.
#Where single-tenant wins
- Enterprise requirements. "Our data must be in its own database," "in this country," "encrypted with our keys," "restorable on demand." Single-tenant answers these directly.
- Noisy neighbors. One tenant running huge reports cannot slow down others if they do not share a database server.
- Customization. Per-customer extensions, schema additions or release timing are manageable when each tenant is separate.
- Blast radius. A bad migration or a runaway query affects one customer.
The cost is operational. Every tenant is a database to monitor, migrate, back up and pay for. Without automation, single-tenant does not scale past a few dozen customers.
#A decision guide
Answer these in order:
- Do you have a free tier or many small customers? Then the default tier must be pooled.
- Do contracts or regulations require physical separation or a specific region per customer? Then those customers need their own database at minimum.
- Do customers need per-tenant restore or data export often? Lean toward bridge or silo.
- Is one tenant's load likely to be orders of magnitude bigger than the median? Give that tenant dedicated compute.
- How many tenants in two years? Thousands favor pool; dozens of large accounts make silo practical.
- How strong is your automation? Silo without automated provisioning and migrations will hurt.
A common, sensible end state: pool by default, silo as an upsell. Build the shared tier with tenant ids and RLS from day one, and design your code so the tenant's database connection is looked up per tenant rather than hard-coded. Moving a large customer out to their own database is then a data copy and a config change, not a rewrite.
#Designing so you can change your mind
Whatever you pick first, these choices keep both doors open:
- A tenant id on every tenant-owned row, even in a single-tenant database. It costs one column and makes later consolidation or extraction easy.
- Tenant resolution in one place. A function that maps a request to a tenant and its database, used everywhere.
- Migrations as files in version control, applied by tooling that can target one database or many.
- No cross-tenant foreign keys. Shared reference data (plans, countries) goes in tables every tenant can read, not keyed to a tenant.
- Per-tenant metering from day one, so you know which tenants would justify dedicated resources.
#Both models on StitchDB
StitchDB supports both ends of the spectrum, with different building blocks.
#Pooled: organizations and RLS
Turn on Organizations in Studio under Authentication → Organizations. It installs tables for organizations, members and invites, SDK functions such as stitchdb.orgs.create() and stitchdb.orgs.invite(), JWT claims (org_id, org_role), and policy helpers you use directly in RLS:
create table public.projects (
id bigint generated always as identity primary key,
org_id uuid not null,
name text not null
);
alter table public.projects enable row level security;
create policy "members read" on public.projects
for select to authenticated using (auth.is_member(org_id));
create policy "admins write" on public.projects
for all to authenticated
using (auth.has_role('admin', org_id))
with check (auth.has_role('admin', org_id));The helpers look up membership live, so removing a member takes effect immediately, even if their token is still valid. Every policy applies to the REST API, Realtime and Storage alike (RLS docs).
#Siloed: a project per tenant
Every StitchDB project is its own Postgres database with its own roles, password, JWT secret and API keys. The Platforms API lets your backend create one per tenant:
POST /projectswith anIdempotency-Key, a template (SQL, a migration list or a copy of an existing project's schema) and seed data applied before the project reports ready.- Labels with your own tenant id, per-project caps on size, requests, connections and end users, and daily usage per project for your own billing.
- Webhooks for lifecycle events, and a claim flow to hand a project to the customer's own account.
For a tenant that needs its own hardware, Scale and Enterprise projects can move to a dedicated server with no change to the project URL or keys.
#Costs and limits to plan for
Be realistic about the silo math. Plans include a set number of projects (Pro 1, Scale 2, Enterprise 10), and each extra project costs $9 a month on Pro, $15 on Scale and $18 on Enterprise, with its own database allowance (as of November 2026; see pricing). That is fine for dozens of paying enterprise tenants, and expensive for thousands of free ones, which is the general rule of single-tenancy on any platform. Also note that StitchDB regions are in the EU only (Germany and Finland), which helps EU residency requirements but does not cover tenants who need data in other regions.
#FAQ
#Is multi-tenant less secure than single-tenant?
Not inherently, but its isolation depends on correct code and policies. With Row Level Security enforced by the database and tested, a pooled design is safe for most products. Single-tenant reduces the consequences of a mistake.
#Can I switch from multi-tenant to single-tenant later?
Yes, if every row carries a tenant id and tenant lookup is centralized. Extracting a tenant is then a filtered copy into a new database plus a routing change.
#What is a hybrid tenancy model?
Most tenants share a pooled environment, while specific tenants (usually large or regulated ones) get dedicated databases or servers. It is the most common model for B2B SaaS at scale.
#How do I stop one tenant from slowing down others?
Per-tenant rate limits and query timeouts in a pool, or moving heavy tenants to their own database or server.
Start with a pooled tier and grow into silos: create a free project and turn on Organizations.