One system serving many separate customers (tenants) whose data must stay fully isolated from each other.
Why it exists
When one system serves many separate customers or organizations, their data must stay isolated even though they share the same software and servers. Multitenancy exists as the design that keeps each tenant's data and settings walled off within shared infrastructure, so one customer never sees another's.
How it actually works
Imagine offering TiffinBox-for-restaurants: many restaurants use the same software, but none can ever see another's orders or data. Multitenancy is building one system that serves them all while keeping each tenant's data strictly separated.
Every query must be scoped to the right tenant, and a mistake here is severe, one customer seeing another's data is a serious breach. It shapes the database design and the permission model from the ground up.
A senior PM walks you through it
A junior PM, stuck
A pilot restaurant on our TiffinBox-for-restaurants product reports seeing orders in their dashboard that are not theirs, orders from other restaurants. This is the exact isolation promise we sold them. I have to write the bug ticket and I do not understand how one restaurant's screen can pull another's data when they are supposed to be separate accounts.
They are separate accounts but they share one table, and one query forgot to say which account it was for. Every row carries a tenant_id marking which restaurant owns it, and the rule is that every read must filter on it. Below is the shared orders table, the query the dashboard actually ran, and the one it should have run. The bug is a single missing WHERE clause, and seeing it will make the ticket write itself.
The shared orders table and the query that leaked across tenants
orders table, all restaurants share it, tenant_id marks the owner
1 id | tenant_id | total | status
2 o_9001 | sultans_dine | 649 | shipped
3 o_9002 | tenant_002 | 280 | cooking
4 o_9003 | sultans_dine | 320 | shipped
5 o_9004 | tenant_003 | 420 | shipped
6 o_9005 | tenant_002 | 150 | cooking
7 o_9006 | sultans_dine | 160 | shipped
the query the dashboard ran, no tenant filter
>SELECT id, total, status FROM orders;
9-- 9 rows returned, from all three restaurants
the query it should have run, scoped to the tenant
>SELECT id, total, status FROM orders WHERE tenant_id = 'sultans_dine';
11-- 3 rows returned, only this restaurant's orders
Click a step to see the lines it points at.
Mistakes I've seen
Logging a cross-tenant leak as a normal bug. One customer seeing another's data is a top-severity isolation breach; filing it at routine priority undersells a risk that can lose the account and breach the contract.
Assuming isolation lives in the UI. Restaurants share one table separated only by tenant_id, so hiding rows on the screen fixes nothing; the filter has to be in the query, at the data layer.
Checking only the endpoint that broke. The same missing tenant filter can hide in any report, export, or new query; a fix that patches one screen and skips the audit leaves the hole open elsewhere.
Promising isolation you have not verified. Customers will ask directly how their data is walled off; answer from how queries are actually scoped, not from an assumption that separate logins mean separate data.
Write the ticket as: "Isolation breach, high severity: the restaurant dashboard's orders query has no WHERE tenant_id, so it returns other tenants' rows. Scope every read to the tenant and audit all queries on this table." You traced a leak to a missing tenant filter and weighted it as the breach it is, which is the skill.
Where a PM meets this
It's fundamental to any B2B product serving multiple companies; isolation guarantees are something customers will ask about directly.
A tenant-isolation bug is among the worst incidents possible; understanding the risk helps you weight it properly in planning.
Hear it in a meeting
"Every query needs a tenant filter, or one client could see another's data."