Multi-Tenant SaaS Architecture: Keeping Customer Data Apart
Key takeaway
Shared schema with a tenant id on every row is the cheapest and most scalable model, and it demands that isolation be enforced in one place — never left to individual queries. Database per tenant buys the strongest isolation and the heaviest operations; choose it when enterprise buyers require it, not by default.
Tenant isolation is the architectural decision in a SaaS product that is hardest to change later, and the one most likely to appear in a customer's security questionnaire.
The three models
- Shared schema — one database, a tenant id column on every table. Lowest cost per tenant, simplest operations, scales to very large tenant counts. Isolation depends entirely on your code being correct.
- Schema per tenant — one database, separate schemas. Cleaner separation and per-tenant export, at the cost of migrations that must run many times.
- Database per tenant — strongest isolation, per-tenant backup, restore, and residency. Highest infrastructure and operational cost, and the model enterprise procurement most often asks for.
If you choose shared schema, enforce it centrally
- Apply the tenant filter in one layer — row-level security in the database, or a single data-access layer that no query bypasses.
- Never accept a tenant id from the client; derive it from the authenticated session.
- Write a test that proves tenant A cannot read tenant B's records, for every entity, and run it on every build.
- Include the tenant id in every log line and metric, so an incident can be scoped quickly.
The problems that appear at scale
- Noisy neighbours — one large tenant's reporting query degrading everyone else. Plan for per-tenant rate limits and separate read capacity.
- Wildly uneven tenant sizes, which break assumptions built around the average customer.
- Per-tenant customisation requests, which quietly become a fork per customer unless they're expressed as configuration.
- Migrations that must run across thousands of schemas or databases within a maintenance window.
A pragmatic path
Start with shared schema and rigorous central enforcement. Keep the tenant boundary explicit everywhere so that moving a single large or regulated customer into a dedicated database later is a deployment decision rather than a rewrite. Hybrid estates — most tenants shared, a handful isolated — are common and entirely reasonable, provided one codebase serves both.