< blog />

Multi-tenant SaaS architecture explained for founders

By Vinicius Ambrozio, founder of VTA Tecnologia · Published

If you are a founder without an engineering background, multi-tenant is the architecture word most likely to appear in a proposal without an explanation. It matters because it is the decision that decides whether your product can be sold to many customers safely, and because the cheap version of it looks identical to the expensive version until the first customer sees another customer's data.

This guide explains the term, the three models the industry actually uses, and the handful of decisions that are hard to undo. It is written for the person who has to approve the architecture, not build it. By the VTA team, who build multi-tenant products and would rather you asked us hard questions than nodded through the proposal.

What does multi-tenant mean, in plain words?

A tenant is one customer of your SaaS: a company, a team, a workspace. Multi-tenant means all of your tenants use the same running copy of the software and the same infrastructure, and the software makes sure each tenant sees only its own data. The alternative, single-tenant, gives every customer its own installation, which is how enterprise software was sold before the cloud and how some regulated products still are.

Multi-tenant is the default for SaaS because it is the only model where the cost of serving one more customer is close to zero. One deployment, one database to back up, one version of the code to keep current. The price of that efficiency is that isolation between customers becomes a property of your code and your schema rather than of separate machines, and code has bugs.

The vocabulary you will hear around this: isolation is the guarantee that tenant A cannot see or affect tenant B. Noisy neighbor is the problem of one tenant's heavy usage slowing everyone else down. Pooled resources are shared across tenants; siloed resources are dedicated to one. Amazon's SaaS Lens for the Well-Architected Framework uses exactly these terms, and it is a good reference to hand a team that needs a shared vocabulary.

What are the three ways to separate tenant data?

Every multi-tenant product answers one question: where does the boundary between tenants live? There are three common answers, and they trade isolation against cost and operational simplicity.

Tenant isolation models
ModelHow it worksStrengthsWeaknessesFits when
Shared database, shared schemaOne set of tables; every row carries a tenant identifier; every query filters by itCheapest to run; one migration per release; simplest backupsIsolation depends on every query being correct; one tenant's data volume affects everyone's indexesMost SaaS products, especially early; small and mid-size customers
Shared database, schema per tenantOne database; each tenant gets its own schema with a copy of the tablesStronger separation; per-tenant restore is possible; queries cannot accidentally cross tenantsMigrations run once per tenant; thousands of schemas strain tooling and connection poolingDozens to a few hundred tenants with distinct data needs
Database per tenantEach tenant has its own database, sometimes its own serverStrongest isolation; per-tenant performance and compliance guarantees; easy to delete a customer entirelyHighest cost; operations multiply with tenants; cross-tenant reporting is hardRegulated industries, large enterprise accounts, contractual data residency

Microsoft's multitenant architecture guidance walks through the same trade-offs in more depth, and its conclusion matches what we see in practice: start pooled, with a shared schema, and move specific large customers to a silo only when a contract or a regulator requires it. Products that start with a database per tenant almost always regret the operational cost before they have enough customers to justify it.

How does row-level security work in Postgres?

In the shared-schema model, isolation is only as good as the discipline of every query. A developer who forgets one WHERE clause on one endpoint has just built a data leak. Row-level security is how you stop relying on discipline and start relying on the database.

Row-level security in PostgreSQL lets you attach a policy to a table that says, in effect, a session may only see rows whose tenant identifier matches the tenant of the current session. The application sets the tenant once, when the request starts, and from then on every query, including the ones a developer forgot to filter, returns only that tenant's rows. If a query would violate the policy, it returns nothing rather than someone else's data.

Managed Postgres platforms have made this mainstream. Supabase's row-level security guide shows the pattern with the tenant resolved from the authenticated user's token, which is the common shape for a product built on it. The cost is some care with performance, because policies run on every query, and some discipline in how background jobs, which have no user session, set their tenant. Both are solvable and both are cheaper than a leak.

What to ask your team: is tenant isolation enforced by the database, or only by the application code? The strong answer names row-level security or an equivalent and can show you the policy. The weak answer is that every query filters by tenant, which is true until it is not.

Which decisions are expensive to reverse?

Most of a multi-tenant architecture can be changed later. A handful of decisions cannot be changed without touching every part of the product, and these are the ones to get right in the first week even in an MVP.

  • A tenant identifier on every table that holds customer data. Not just the top-level ones. The comment on the task on the project in the workspace also belongs to a tenant, and the query that fetches comments for a report will eventually be written by someone who does not know that.
  • Where the tenant is resolved. From the subdomain, from the user's membership, from a header. Pick one, do it in one place at the start of every request, and never let an endpoint take a tenant identifier from the request body. That last mistake is how one customer's export ends up filtered by another customer's identifier.
  • How users relate to tenants. Can one person belong to several workspaces? Decide now. Retrofitting a many-to-many relationship between users and tenants onto a product built with one user per tenant is a rewrite of authentication.
  • How files are stored. Object storage paths should include the tenant from day one, and signed URLs should be scoped so that a link to one tenant's file cannot be guessed into another's.
  • How background jobs carry the tenant. A nightly export, an email digest, a webhook retry: each runs without a user session and has to set its tenant explicitly. Jobs that loop over all tenants and forget to reset the context between them are a classic leak.
  • What the customer identifier at the payment provider maps to. One Stripe customer per tenant, stored on the tenant record, so billing events from webhooks land on the right workspace. Our SaaS billing guide covers the details.

What about the noisy neighbor problem?

In a pooled model, one tenant importing a million rows on a Monday morning can slow every other tenant's dashboard. Early on, this is a theoretical problem, and solving it early is a way to spend money you do not have on customers you do not have yet. Later, it becomes real, and the fixes are known: rate limits per tenant, background jobs in a queue with per-tenant fairness, database indexes that lead with the tenant identifier so one tenant's data does not sit in everyone's way, and, for the largest accounts, a move to their own database.

The design decision to make now is smaller: make sure the tenant identifier is the first column in the indexes that matter, and make sure heavy operations already run as background jobs rather than inside a web request. Both are cheap on day one and make every later fix possible.

What should a founder ask the team to show?

You do not need to read the code. You need to see five things exist.

  • The tenant column on a table three levels deep in the data model, not only on the workspace table.
  • The row-level security policy, or whatever enforces isolation at the database, and a test that proves a query for tenant A returns nothing from tenant B.
  • The single place where the tenant is resolved at the start of a request.
  • A background job that sets its tenant explicitly, and the test that checks it.
  • The storage path of an uploaded file, with the tenant in it.

A team that can show those five in an afternoon has built multi-tenant products before. A team that explains why they are not needed yet has not, and you will be paying for the lesson. The twelve questions to ask a SaaS development company include this one for a reason. When you are ready to talk about a specific product, our SaaS development page describes how we approach the first release.

Glossary

The terms that come up in a multi-tenant proposal, in one place.

  • Tenant. One customer of the SaaS: a company, a team or a workspace, with its own users and data.
  • Isolation. The guarantee that one tenant cannot see or affect another tenant's data or performance.
  • Pooled. Infrastructure shared across tenants. Cheapest to run; isolation is enforced by code and schema.
  • Siloed. Infrastructure dedicated to one tenant. Strongest isolation; most expensive to run.
  • Row-level security. A database feature that attaches a filter policy to a table so that every query returns only the rows the current session is allowed to see.
  • Noisy neighbor. One tenant's heavy usage degrading performance for the others in a pooled setup.
  • Tenant context. The tenant identifier resolved at the start of a request or job and used by every query that follows.
  • Data residency. A contractual or legal requirement that a tenant's data stays in a specific country or region, which usually forces a silo.

The detail on the work itself

Frequently asked questions

What is multi-tenant architecture in SaaS?

An architecture where many customers, called tenants, share one running copy of the software and the same infrastructure while each one sees only its own data. It is the default for SaaS because serving one more customer costs almost nothing, and its main risk is that isolation between customers is a property of the code and schema rather than of separate machines.

Should I use one database per customer?

Usually not at the start. A database per tenant gives the strongest isolation and the highest operating cost, and its overhead is felt long before you have enough customers to justify it. Start with a shared schema and a tenant column on every table, enforce isolation with row-level security, and move specific large or regulated customers to their own database when a contract requires it.

What is row-level security and do I need it?

A database feature, available in PostgreSQL, that attaches a policy to a table so every query returns only rows belonging to the current session's tenant, including queries a developer forgot to filter. If your product is multi-tenant with a shared schema, you want it or an equivalent, because relying on every query being correct is relying on nobody ever making a mistake.

Can a user belong to more than one tenant?

Only if the data model was designed for it. Deciding this in the first week is cheap. Retrofitting many-to-many membership onto a product built with one user per workspace means rewriting authentication and every screen that assumes a single workspace.

How do I know my SaaS is isolating tenants correctly?

Ask the team to show a tenant column on a deeply nested table, the policy that enforces isolation at the database, the single place where the tenant is resolved per request, a background job that sets its tenant explicitly, and a file storage path that includes the tenant. Then ask for the test that proves a query for one tenant returns nothing from another.

Does multi-tenant mean less secure?

Not inherently. Most large SaaS products you use daily are multi-tenant. It means security depends on the schema and the code enforcing isolation rather than on physical separation, so the enforcement has to be at the database and tested, not left to the discipline of every developer who ever touches a query.

Keep reading

Want a number for your own project?

Tell us what you are building and you get a written scope, a fixed price and a delivery date within 24 hours.