All insights

INSIGHTS · 6 MIN READ

How to build a multi-tenant SaaS without leaking customer data

The worst bug a SaaS product can have is showing one customer another customer's data. It is also one of the easiest to introduce, because a single missing filter in a single query is enough. Good multi-tenant design makes that mistake hard to make, and easy to catch.

By Itzhak Shaul · October 11, 2026

1. Put the tenant on every row

Every table that holds customer data carries a tenant identifier, with no exceptions for 'small' tables. Make it part of the primary key or a mandatory foreign key, and put it first in composite indexes so queries for one tenant stay fast as the product grows.

2. Enforce isolation in the database, not only in code

Application filters such as WHERE tenant_id = ? are necessary, but they depend on every developer remembering them forever. PostgreSQL row-level security (RLS) adds a second lock: the database itself refuses to return rows that belong to another tenant.

Two details matter. First, the application must connect with a role that does not own the tables, because table owners bypass RLS unless you use FORCE ROW LEVEL SECURITY. Second, set the current tenant per transaction (for example with a transaction-local setting) so a pooled connection can never carry one tenant's identity into another request.

3. Carry the tenant through everything that runs later

Isolation often breaks outside the request path: background jobs, scheduled tasks, webhooks, exports and file storage. Every job payload should include the tenant, and the worker should establish the same database context before doing anything. Storage paths and cache keys should include the tenant as well.

4. Isolate AI knowledge too

If the product includes an AI assistant that answers from customer content, the knowledge base needs the same boundary. Use a separate vector namespace per tenant, or at minimum a mandatory tenant filter on every retrieval, and never let the model see content retrieved for another tenant. Treat this as a security requirement, not a feature detail.

5. Permissions inside a tenant

Tenant isolation separates companies; role-based access control separates people inside a company. Design both from the start. Adding roles later usually means touching every query and screen.

6. Prove it with tests

Write tests that deliberately try to cross the boundary: create data in tenant A, then attempt to read, update and delete it as tenant B through every API route and background job. Run them in CI. Also test that a request with no tenant context returns nothing rather than everything.

7. Plan for operations

Decide early how you will back up and restore a single tenant, how you will delete a tenant's data on request, and how you will log access without writing personal data into logs. These are much harder to add after launch.

Multi-tenancy is mostly a set of small decisions made early and enforced in more than one place. If you are planning a SaaS product or reviewing an existing one, an architecture review before the first customer is far cheaper than a data-leak investigation after.

Discuss your project

More articles

When not to build an AI agent, and what to build instead · Modernizing a legacy .NET system without a risky rewrite