Quavon Development
SaaS4 min read

Multi-tenancy is the decision that costs most to retrofit

Almost every SaaS platform makes this decision too late. What that costs later, and how we settled it in our own products.

Leopold LinkCo-founder & developerPublished
The short answer

Settle tenant separation before the first migration and enforce it in the database, not the application. Retrofitted, the separation hangs on a condition in every single query — and one forgotten condition is a data leak, not a bug.

Multi-tenancy means every customer uses the same application while each sees only their own data. It sounds like any other requirement. It is the one you effectively cannot retrofit without rewriting the database.

Why retrofitting gets expensive

Start without a tenancy model and you end up filtering in the application. Every query gains an extra condition on the organisation. That works as long as every query remembers. At two hundred queries one will not, and then customer A sees customer B's data.

What separates this from an ordinary defect is the class of damage. A miscalculated discount is a ticket. A leak between two customers is a reportable GDPR incident, a loss of trust, and depending on the sector a contractual problem.

Where the separation belongs

In the database. Row level security in PostgreSQL enforces the separation where the data lives: a query without a valid tenant context returns no rows, whatever the application code forgot. The application can no longer bypass the rule, because it no longer knows it.

  • A tenant column on every table holding customer data — no exceptions
  • Row level security enabled, not merely defined
  • The tenant context comes from the session, never from a request parameter
  • A test that queries without context and proves nothing comes back

What that looks like in practice

For Enclessa, confidentiality was the precondition of the product: direct messages are end-to-end encrypted with MLS (RFC 9420), hosted in the EU. For TixFin it is organisers sharing seat maps and payments in real time without two organisers ever seeing the same row. Both settled their tenancy model before the first migration, because we knew the alternative was building it twice.

Any decision you can change later is one you may take later. Data separation is not one of them.

The check

Taking over an existing platform, this is the first question: what does the separation hang on? If the answer lives in the application, the honest estimate for changing it is not a sprint but a migration with a downtime window. That is why we read the code before writing a quote.

FAQ

Questions that come after

Answered briefly, and each answer written to stand on its own — quoted somewhere else, it still says something true.

01What does multi-tenancy mean in a SaaS application?

Multi-tenancy means every customer uses the same running application and the same database while each sees only their own data. A tenant is the organisation, not the individual user: ten colleagues at one company share a tenant, two companies never do.

02Why can multi-tenancy not simply be added later?

Because tenancy has to be recorded in every table that holds customer data. Adding it later means a column on each of those tables, a value for every existing row, a new index behind every query, and a condition in every single query. That is not a change in one place; it is a migration across the whole dataset.

03What is row level security, and why is an application filter not enough?

Row level security is a PostgreSQL feature that decides per row whether the current session may see it. An application filter only applies in the queries that remember it; row level security applies in all of them, including the ones somebody writes next year and the ones run straight from a console.

04When does a separate database per tenant make sense?

When a customer requires physical separation by contract, when individual tenants are large enough to distort the load of the rest, or when retention periods differ per customer. The price is operations: every migration then runs per database, and schema versions that drift apart get expensive quickly.

05Is a leak between two tenants reportable under GDPR?

As a rule, yes. If customer A sees customer B's personal data, that is a personal data breach under Art. 4(12) GDPR and has to be reported to the supervisory authority within 72 hours under Art. 33 GDPR unless a risk to the people concerned can be ruled out. This is a legal characterisation, not legal advice.

06How can I tell whether an existing platform is properly separated?

By a test, not by an assurance. Run a query with no valid tenant context: if rows come back, the separation lives in the application. Second check: look for a table holding customer data with no tenant column. If you find one, separation is already unenforceable there.

Starten wir durch

Want this looked at properly?

Tell us what you are building. You get an honest read on scope, schedule and risk — and a clear answer on whether we are the right team for it.

Antwort in der Regel innerhalb von 24 Stunden