What discrete manufacturing taught us about choosing a tenant isolation model
What choosing a tenant isolation model actually looked like from inside a contract manufacturer running three lines.
This one starts in a room with production planners and a whiteboard covered in arrows. They'd built a workable process around a system that fought them at every step, and the workarounds had quietly become the institutional knowledge. Nobody could describe the job without describing the workarounds.
Tenant isolation is one of the few decisions that's genuinely hard to change later, because it reaches into every query and every backup. Pick it deliberately, on the basis of what happens when you get it wrong, not on what's fastest to start.
THE THREE OPTIONS
A shared table with a tenant column is cheapest to build and cheapest to operate, and it puts one WHERE clause between your clients and each other's data. A schema per tenant costs more operationally and makes the isolation structural. A database per tenant is expensive and unambiguous.
There's no universally right answer. There's a right answer given how many tenants you expect, how different their data volumes are, and what the consequence of a leak actually is. Ten enterprise clients with audit requirements and ten thousand self-serve accounts want different answers.
THE FORGOTTEN WHERE CLAUSE
With shared tables, the whole model rests on every query being filtered, forever, by everyone. That's not a thing humans do reliably. So it can't be a convention. It has to be enforced somewhere that a new engineer can't route around, whether that's row-level security in the database or a query layer that won't build an unscoped statement.
Test it adversarially. Write a test that tries to read another tenant's row through every access path you have, and treat a pass as a load-bearing part of the suite. The one path nobody tested is the one that leaks, and it's usually a report or an export.
The clearest thing we saw was how production planners handled a contested work instruction. On paper it's one step. In practice it's five, three of them over the phone, none of them written down. Which is why nobody could ever explain schedule adherence to their director.
THE PARTS PEOPLE FORGET
Isolation doesn't stop at the table. It applies to backups. Can you restore one tenant without the others? To exports, to logs, to error reports, to caches keyed carelessly. Each of those has leaked somewhere, and the cache key is the one that catches good teams.
Also plan for the tenant that's a hundred times larger than the rest. In a shared model, their data volume becomes everyone's query planner problem, and that conversation arrives with no warning.
Here it showed up as a queue nobody owned. About 30,000 units a week went through it, and production planners had learned to check it twice a day because the alternative was a revised instruction reached the floor after the batch had run. A better queue wasn't the answer. Making ownership a property of the work instruction was.
WHERE IT GOES WRONG
- No way to restore a single tenant, so every recovery is all-or-nothing.
- One tenant a hundred times bigger than the rest, quietly ruining everyone's query plans.
- A missing WHERE clause in a report path that nobody tested adversarially.
- Cache keys without the tenant in them, serving one client's data to another.
Isolation has to be structural. A convention that everyone must remember isn't isolation.
WHAT WE TOOK AWAY
The work shipped and schedule adherence moved, but the thing we're proudest of is smaller than the system: production planners stopped keeping a private spreadsheet. That's usually the honest signal that the model finally matches the job.