net·devs
← All insights
File insight
4 min readBy Kyrylo Osadchuksaasarchitecture

How to make the multi-tenancy decision you cannot easily reverse

Shared-database with row-level isolation, schema-per-tenant, or database-per-tenant. The wrong choice is survivable for a while, then it isn't. How to make it deliberately.

Multi-tenancy is one of the few SaaS architecture decisions that genuinely deserves the word "irreversible." Not strictly irreversible — every architecture can be changed, given enough money and an outage window — but expensive enough to change that most teams who pick wrong live with the wrong choice for years.

The three options are well known: shared database with row-level tenant isolation, schema-per-tenant inside a shared database, or database-per-tenant. Most articles on the topic stop at listing them. The interesting question is which one fits which business, and the answer depends on properties of your customers, not properties of your code.

What the three models actually look like

Quickly, for shared vocabulary:

Shared-database, row-level isolation. One database. One schema. Every table has a tenant_id column. Every query has a WHERE tenant_id = ? clause. Tenant isolation is enforced at the application layer. This is the default for most SaaS products and the easiest to build.

Schema-per-tenant. One database. A separate schema per customer. The application connects with a tenant-specific search path or schema-qualified queries. Isolation is enforced by the database boundary between schemas. Backups, restores, and migrations happen per schema.

Database-per-tenant. A separate database per customer. The application maintains a pool of connections, picks the right database for the request, and routes accordingly. Isolation is enforced by the strongest boundary the database engine offers.

There are also variants — shared database with row-level security policies (Postgres RLS), hybrid models where some tables are shared and others are per-tenant, and managed solutions like Aurora Serverless or per-tenant DynamoDB tables. The decision framework applies to those too.

The four factors that decide

Four properties of your business determine which model fits. Most teams overweight the third and underweight the others.

Tenant size distribution. If your tenants are roughly equal in size — small businesses each using maybe 100MB of data — shared-database works well and the operational simplicity is enormous. If your tenants vary by three orders of magnitude — some have 1MB, some have a terabyte — shared-database starts producing pathological query plans on the small tenants because the index statistics are dominated by the large ones. Schema-per-tenant or database-per-tenant becomes structurally better.

Noisy-neighbor risk. Some customer workloads are bursty in ways that affect other customers. A reporting query that scans a tenant's entire history can lock up the shared database if it is built badly. In a shared model, one customer's mistake degrades everyone. The cost of isolation is real, but so is the cost of not having it for customers whose work is uneven in load.

Regulatory and contractual constraints. Some customers will sign an enterprise contract only if their data lives in a database that is theirs alone. Some industries — healthcare, financial services — make this a default expectation rather than an exception. If your sales team is going to encounter this in the next two years, building shared-database now means a migration later. The migration is the expensive part of the entire architecture decision.

Operational maturity. A shared database is one thing to back up, one thing to patch, one thing to migrate. A thousand databases is a thousand things. Database-per-tenant works only if your operational tooling can treat the thousand as a fleet — automated provisioning, automated patching, automated backup verification, automated cost monitoring. Teams that pick database-per-tenant without this tooling drown in operations within a year.

The decision framework

Map the four factors honestly:

  • Tenants are uniform in size, no noisy-neighbor concerns, no regulatory pressure, small ops team → shared-database. This is the right answer for most early-stage SaaS.

  • Tenants vary by an order of magnitude or two, some are large enough to cause noisy-neighbor issues, no regulatory pressure → schema-per-tenant. Gets you isolation without the operational explosion of separate databases.

  • Tenants include enterprise customers who require data-level isolation, regulatory constraints in scope, ops team has fleet tooling → database-per-tenant. Often the right answer for sales-led enterprise SaaS, almost always the wrong answer for self-serve SaaS.

The hybrid model — some shared, some per-tenant — is often the actual destination after a few years of growth. It is not a model to start with. It is the result of starting in one place and discovering that the other model is right for a specific subset of customers.

What to build now even if you change later

A few habits make the eventual migration cheaper, whichever model you start with.

Make tenant ID a first-class concept in your domain model from day one. Even in a single-tenant prototype, the data model should have it. Backfilling this is painful; designing it in is free.

Treat tenant scoping as a single piece of code, not a WHERE clause sprinkled everywhere. A repository layer or query builder that automatically injects the scope means tenant-isolation bugs become very rare. Hand-written queries that "remember" to include the filter mean tenant-isolation bugs become inevitable. We have seen real money lost over this.

Build your connection pooling abstraction to support per-tenant routing, even if you do not use it. When migration day comes, the wiring is already there. This is one of the cheapest pieces of forward investment you can make.

Run a "what would migration cost?" exercise every six months. Not because you are about to do it, but because the answer drifts as the system grows. A migration that would cost a week today might cost a quarter in eighteen months. Knowing the number lets you choose to act on it deliberately.

The honest summary

The multi-tenancy choice is genuinely hard, and it is genuinely worth taking time over. It is not a decision the engineering team can make alone — the answer depends on who you sell to, and how that will change in the next three years. Get the sales leadership and the engineering leadership in the same room before deciding. The teams who lose money on this decision usually lost it in the room where the decision was actually a default rather than a discussion.

We want to hear your thoughts.

A senior engineer reads every message — no SDR funnel.