Building SaaS

Multi-tenant SaaS architecture: tenancy models, data isolation and trade-offs

Silo, pool and bridge tenancy explained, three ways to isolate tenant data, and the cost of 200 tenants on shared and dedicated databases worked through.

Isometric 3D illustration of a green cube built from many identical small spheres, floating above its shadow, on a pale green-grey background.

You are designing a SaaS product, or rebuilding one, and you have to decide whether customers share a database. A large prospect asks whether their data sits next to anyone else’s. Your cloud bill depends on the answer, and so does your next security review.

A tenant is one customer account in a SaaS product: in business software, a company and all of its users. Running many tenants on one shared system is a large part of what makes SaaS cheaper to operate than one installation per customer, as explained in What is SaaS?. How much you share, and how you keep tenants apart, is the architecture decision this guide covers.

Multi-tenancy in plain terms

Think of housing. In a street of detached houses, each family has its own walls, pipes and bills. In an apartment building, families share the foundation and the plumbing, and each has a locked door. Some buildings mix the two: most flats share everything, a few penthouses have a private lift. Detached houses are private and expensive. Apartments are cheap, and only as safe as their locks.

Cloud vendors use names for the same three choices. In AWS’s terms, the silo model gives a tenant dedicated resources, the pool model shares resources among tenants, and the bridge model mixes the two. AWS adds that a silo still shares one identity, onboarding and operations layer for all tenants. Without that layer, you are running a managed service, not SaaS.

The tenancy models compared

Microsoft’s Azure Architecture Center splits the middle ground in two. The table maps both vendors’ terms.

Model (AWS / Microsoft) What is shared How tenants are kept apart Cost per tenant Main risk
Silo / automated single-tenant Identity, onboarding, operations Separate infrastructure per tenant Highest: Microsoft notes 100 tenants “probably require 100 times that cost” Updates and fixes across many deployments
Pool / fully multitenant Everything Application code and a tenant ID Lowest A bug leaks data; one heavy tenant slows the rest; one bad change hits everyone
Bridge / vertically partitioned Most tenants pooled, some on dedicated deployments Both, depending on the tenant Middle Code must support both modes, and moving a tenant is a migration
Bridge / horizontally partitioned The application tier; each tenant gets its own database Separate data, shared compute Middle Automating many per-tenant components

The vertical split is often a pricing decision too. Microsoft points out that you can charge more for a single-tenant deployment to recover its cost.

Three ways to isolate data in a database

  1. Row level. All tenants share the same tables, and every row carries a tenant ID. This is the cheapest option and the easiest to get wrong, because one query without the tenant filter returns everyone’s data.
  2. Schema per tenant. One database holds a separate set of tables for each tenant. A missing filter no longer leaks data, but every schema change runs once per tenant.
  3. Database per tenant. Each tenant has its own database, the horizontally partitioned model above. Isolation and per-tenant backups are simple; the fleet of databases is not.

For row-level isolation, the database can enforce the filter for you. PostgreSQL’s row security policies restrict which rows normal queries return. With row security enabled and no policy defined, PostgreSQL applies “a default-deny policy”, so no rows are visible. But superusers and roles with the BYPASSRLS attribute always bypass it, and table owners normally do too, unless the table is set to FORCE ROW LEVEL SECURITY. If your application connects as the table owner, the policies may not apply to it.

Login is not isolation

AWS makes a point that many teams miss. Authentication tells you who the user is, and authorization tells you what they may do. Neither stops a request from reaching another tenant’s data. In AWS’s words, “a user could be authenticated and authorized, and still access the resources of another tenant.” Isolation means every data access is scoped by the current tenant’s context, enforced separately from login.

Noisy neighbors

In a shared system, one tenant’s load becomes everyone’s problem. Microsoft’s example: if a large tenant runs a heavy query or operation, “it might affect other tenants.” The usual controls start with per-tenant rate limits and quotas. Beyond that, you can move the heaviest tenants to dedicated resources (the vertical split). Or you can give each tenant its own copy of the component under the most load (the horizontal split).

Worked example: 200 tenants, three designs

Example: a labeled hypothetical with round prices. You have 200 tenants. A shared database cluster that serves all of them costs $1,500 a month. The smallest dedicated database costs $25 a month. Each schema migration takes 3 minutes to run and check per database.

  • Pool: $1,500 / 200 = $7.50 per tenant a month. One migration run per release.
  • Database per tenant: 200 x $25 = $5,000 a month, or $25 per tenant. Each release runs 200 migrations: 200 x 3 = 600 minutes, or 10 hours of pipeline time.
  • Bridge: 190 tenants stay on the $1,500 cluster, and 10 enterprise tenants get a dedicated $400 database each. Cost: $1,500 + 10 x $400 = $5,500 a month. If each of the 10 pays a $1,000 monthly isolation premium, that is $10,000 a month of revenue against $4,000 of dedicated cost.

The pool is cheapest by a wide margin: $1,500 against $5,000. Database per tenant costs 3.3 times as much ($5,000 / $1,500) and adds 10 hours to every release. The bridge keeps the pool’s economics for 190 tenants ($1,500 / 190 = $7.89 each) and turns isolation into a product the 10 large tenants pay for.

Which model to start with

  • Many small customers who sign up on their own: pool, with row-level isolation enforced in the database and tested.
  • A few customers ask for isolation in security reviews: bridge. Keep the pool and sell dedicated databases or deployments as a higher tier.
  • Regulated customers who require dedicated infrastructure: silo, automated from day one. Microsoft’s example is software for legal firms whose customers insist on their own infrastructure.
  • A handful of very large customers: silo can be fine, because the per-tenant cost is small next to each contract.

Where the infrastructure runs matters as well. For the AWS building blocks, see SaaS on AWS. For serving each tenant on its own domain, see Cloudflare for SaaS. If a customer asks for a copy in their own data center, that is a different model, covered in SaaS vs on-premise.

Common mistakes

  1. Treating login as isolation. An authenticated user with the right role can still reach another tenant’s rows if a query forgets the filter. Why it happens: the identity provider feels like the security layer. Instead: scope every data access by tenant, and enforce it in the database where you can.
  2. Running the application as the table owner. In PostgreSQL, owners normally bypass row security, so the policies you wrote may never run. Why it happens: the migration user and the app user are the same account. Instead: give the application its own role, or force row security on the table.
  3. Choosing silo without automation. Every deployment needs updates, and Microsoft warns that maintenance “can be time consuming”. Why it happens: the first five tenants are easy to manage by hand. Instead: script provisioning and upgrades before tenant number ten.
  4. Never testing isolation. A leak shows up in a customer’s screenshot, not in your logs. Why it happens: tests use one tenant at a time. Instead: add automated tests that log in as tenant A and try to read tenant B, as Microsoft’s guide advises.

Sources

In three sentences

Multi-tenant SaaS runs many customers on shared infrastructure, and the choice is how much to share: everything (pool), nothing but identity and operations (silo), or a mix (bridge). In the example, 200 tenants cost $1,500 a month pooled and $5,000 on dedicated databases, while a bridge keeps pooled costs and charges 10 large tenants for isolation. Whatever you choose, enforce tenant scope on every data access, keep the app from bypassing database policies, and test that one tenant cannot read another’s data.