
Multi-tenant SaaS architecture means one running application serving many customer companies, called tenants, while keeping each tenant's data separate from every other's. For most SaaS MVPs the right starting point is one application and one PostgreSQL database, with every table keyed by tenant and the separation enforced in the database as well as in the code.
That setup is cheap to run, simple to deploy and safe if it's built carefully. This article covers the patterns, the trade-offs between them, and the rules that stop one customer seeing another's data.
What is multi-tenant SaaS architecture?
Multi-tenant SaaS architecture is a design where one application, and usually one database, serves many customer companies at once while keeping each company's data separate. Each customer account is a tenant: usually a company, with its own users, data, settings and subscription. All tenants share the system rather than each getting a private copy.
The alternative is single-tenant: a separate deployment for every customer. That gives the strongest separation, but every new customer means another set of servers to run, update and pay for.
Most B2B SaaS products are multi-tenant because the economics work. You deploy once, fix a bug once, and the cost of each additional customer is small. The engineering challenge is making sure that sharing the system never means sharing the data.
What are the main multi-tenant architecture patterns?
There are three main multi-tenant architecture patterns: silo, pool and bridge. The names come from Amazon's guide to SaaS tenant isolation strategies:
- Silo: each tenant gets its own resources, such as its own database or its own deployment.
- Pool: tenants share resources and are kept apart by rules in the application and database.
- Bridge: a mix, where some layers are shared and others are separate.
Microsoft's guide to tenancy models uses different words for the same range: fully multitenant deployments where everything is shared, automated single-tenant deployments where each tenant gets its own infrastructure, and partitioned approaches in between, such as one shared application with a separate database per tenant.
The trade-off is the same in both. The more you share, the lower the cost per tenant and the simpler the operations. The more you separate, the stronger the isolation and the more you spend. Microsoft notes that single-tenant deployments avoid one tenant's load affecting another, at the price of low cost efficiency.
How should a multi-tenant SaaS store its data?
A multi-tenant SaaS can store data in one shared database with a tenant ID on every row, in one database with a separate schema per tenant, or in a separate database for each tenant. Most MVPs should use the shared database with row-level security switched on. The diagram at the top of this article shows all three side by side, from most shared to most separate.
One shared database, tenant ID on every row. All tenants live in the same tables, and every row carries the ID of the tenant it belongs to. It's the cheapest and simplest to run, and the easiest to change: one migration updates everyone. The risk is that a missed filter in a query can expose another tenant's rows, which is why the database itself should enforce the separation.
One database, a schema per tenant. Each tenant gets its own set of tables inside a shared database. Separation is clearer, but every schema change has to run once per tenant, which gets slow and fragile as the number of tenants grows.
A database per tenant. The strongest separation short of separate deployments. It's easy to back up, restore or delete one tenant, and to place a tenant's data in a particular region. It's also the most expensive and the most work to operate at scale.
Microsoft's guide to storage and data in multitenant solutions goes through these in more depth. Many products end up mixing them: shared tables for most customers, and a dedicated database for the few that need one.
How does tenant isolation work in a multi-tenant SaaS?
Tenant isolation works by enforcing the separation at every layer: the application takes the tenant from the signed-in session, the database refuses to return other tenants' rows, and automated tests check that it holds. That way one missed check doesn't become a data leak. In practice it comes down to seven rules.
- Every row belongs to a tenant. Each tenant-owned table has a tenant ID column that can't be empty.
- The tenant comes from the session, never from the request. The application works out which tenant a user belongs to when they sign in. It never trusts a tenant ID sent in a URL or form field.
- The database enforces it too. PostgreSQL's row security policies let the database refuse to return rows from another tenant, even if a query forgets to filter.
- Uniqueness is per tenant. A rule like "invoice numbers must be unique" should mean unique within one tenant, not across all of them.
- Background jobs carry the tenant. Scheduled tasks, queues, webhooks and any AI automations running on customer data need to know which tenant they're working for, just like a web request does.
- Files and caches are scoped. Uploaded files and cached data should sit under a tenant-specific key, so one tenant's URL can never fetch another's file.
- Tests try to break it. Automated tests that sign in as one tenant and try to read another's data are the cheapest insurance there is.
Row-level security is the line that matters most. It turns "every developer must remember the filter on every query" into "the database won't allow it".
What about noisy neighbours?
A noisy neighbour is one tenant using so much of a shared resource that everyone else slows down: a huge import, a report that scans millions of rows, or a burst of API calls. Microsoft describes it as a common risk in shared systems in its noisy neighbour antipattern guide.
The usual protections, roughly in the order you'll need them:
- Rate limits per tenant on the API.
- Heavy work, such as imports and exports, moved to background queues that share capacity fairly between tenants.
- Monitoring that shows resource use by tenant, so you can see who is causing a slowdown.
- Moving a very large tenant to its own database, which is the bridge pattern in practice.
An MVP rarely needs more than the first two. The point is to build in a way that makes the last two possible without a rewrite.
What does a SaaS MVP actually need?
A SaaS MVP needs one shared application and database, a tenant ID on every tenant-owned table with row-level security, sign-up, roles and billing that all belong to the tenant, and tests that check isolation. That's less than most architecture diagrams suggest. For a first version:
- One application and one PostgreSQL database, shared by all tenants.
- A tenant ID on every tenant-owned table, with row-level security switched on.
- Sign-up that creates a tenant and its first user, and invites that add users to it.
- Roles within each tenant, so the owner can manage billing and members.
- Billing attached to the tenant, not the individual user, since the company is what pays.
- Per-tenant settings stored as data, rather than code branches for particular customers.
- Tests that check one tenant can't read another's data.
What can wait: a database per tenant, per-tenant deployments, data residency in multiple regions, and custom infrastructure for enterprise customers. Build those when a paying customer needs them, which is easy if every record already knows its tenant.
This is what we mean by multi-tenant from the first commit in our SaaS MVP development services. It's also why we put it on the list of things version one has to get right in how to choose a SaaS MVP development agency, and why the MVP vs prototype distinction matters: a prototype can fake tenancy, an MVP can't.
When should a tenant get its own database?
A tenant should get its own database when a contract, a regulator, a data-location rule or the tenant's sheer size makes sharing the wrong answer. The usual triggers:
- A customer's contract or regulator requires their data to be physically separate.
- Data has to stay in a particular country or region.
- One tenant is large enough to affect everyone else's performance.
- A customer needs their own backup and restore schedule, or to be deleted completely and provably.
If every row already carries a tenant ID, moving one tenant to a dedicated database is a contained piece of work: copy their rows, point their requests at the new database, and keep the same code. If the product was built without tenancy, the same change touches nearly every query.
Can you convert a single-tenant app to multi-tenant later?
Yes, a single-tenant app can be converted to multi-tenant later, but it costs more than building tenancy in from the start. Every table needs a tenant column and a backfill, every query needs reviewing, every unique rule needs rescoping, and background jobs, files and caches all need tenant context added. Teams usually find a few places where data had quietly been shared.
If a product is likely to serve more than one customer company, the cheapest time to make it multi-tenant is before the first one signs up.
A multi-tenant checklist for your MVP
- Every tenant-owned table has a non-empty tenant ID.
- Row-level security is on for those tables.
- The tenant is taken from the signed-in session, never from request input.
- Unique constraints are scoped to the tenant.
- Background jobs, files and caches carry tenant context.
- Billing belongs to the tenant.
- Automated tests try to read across tenants and fail.
- Resource use can be seen per tenant.
If you're planning a SaaS product and want the tenancy decided before the first line of code, contact us to get started. You can also see everything we build.
Common questions
What is the difference between single-tenant and multi-tenant SaaS?
In single-tenant SaaS each customer gets their own deployment of the application and its infrastructure. In multi-tenant SaaS all customers share one application, and often one database, with their data kept separate by rules. Multi-tenant is cheaper and simpler to run; single-tenant gives the strongest isolation.
Is multi-tenant SaaS secure?
It can be, if separation is enforced at more than one layer. The application should take the tenant from the signed-in session, the database should enforce row-level security, and automated tests should check that one tenant can't read another's data. Most leaks come from relying on a single filter in application code.
Should every SaaS MVP be multi-tenant?
Any product sold to more than one customer company should be built tenant-aware from the start, even if some enterprise customers later get dedicated infrastructure. Adding tenancy to an existing product means touching nearly every table and query, which costs far more than designing it in.
What is row-level security in PostgreSQL?
It's a database feature that restricts which rows a query can see or change, based on a policy. In a multi-tenant product the policy says a session can only access rows belonging to its own tenant, so even a query that forgets to filter by tenant returns nothing it shouldn't.
Which database model is best for a multi-tenant SaaS?
For most products, one shared database with a tenant ID on every row and row-level security enabled. It's the cheapest and easiest to change. Move individual tenants to their own database when a contract, regulation, data-location rule or their size requires it.
How do subdomains or custom domains work in a multi-tenant SaaS?
The application maps each subdomain or custom domain to a tenant, then uses that tenant for the request, alongside the signed-in user's own account. The data model doesn't change: the domain is just another way of identifying which tenant a request belongs to, and access is still checked against the user's membership.
Want something like this built and run in your own accounts? That's what our SaaS Development service does. You can also see everything we build or look through our case studies.


