One table, everybody's records

Open the CRM you pay for every month. Your customer list is in there — names, phone numbers, deal sizes, the notes your salesperson wrote about why a deal went cold. Now picture the table those rows are stored in. Your competitor's customer list is in the same table. So is everybody else's.

What keeps them apart is not a wall. It is a condition attached to a query — an instruction to only return the rows where the account column matches yours. It works when it is there. It has to be there every single time, in every query, in every feature, written by every developer who has ever touched the product.

01 The Mechanism

What Actually Separates Your Records From a Stranger's

Software sold as a monthly subscription is almost always multi-tenant. One running copy of the application serves every customer, and one database holds everybody's data. Each row carries a column saying which account it belongs to, and the application's job is to never forget to filter on it.

That design is not laziness — it is what makes the price possible. Running one system for ten thousand customers is enormously cheaper than running ten thousand systems, and every efficiency of that model gets passed along in the subscription fee. When software costs a few tens of dollars a month, this is the reason.

The consequence is that isolation becomes a property of correctness rather than a property of structure. Nothing physical is separating tenants. The separation is a rule the code applies, and rules that have to be applied consistently across thousands of code paths, for years, by rotating teams, are exactly the kind of rule that eventually is not applied somewhere.

The wall between you and ten thousand strangers is a condition in a query somebody has to remember to write.
02 The Honest Part

Row-Level Security Is a Real Control, and It Mostly Works

Good multi-tenant products do not rely on developers remembering. They use row-level security, which moves the tenant filter out of application code and into the database itself. The database is told that this table may only ever return rows matching the current account, and it enforces that regardless of what the application asks for. A query that forgets its filter returns nothing instead of returning everything.

This is a genuine improvement and it deserves credit. It converts a mistake that leaks data into a mistake that shows an empty screen, which is the right direction for a failure to fall. Any serious multi-tenant vendor uses it, and we use it ourselves where a system is legitimately shared.

The word carrying the weight is mostly. The policy has to be enabled on every table, including the one added last week. It has to be written correctly, and a policy with a subtly wrong condition enforces the wrong thing confidently. It has to survive privileged connections — background jobs, admin tooling, reporting pipelines and data exports frequently run with credentials that bypass it, because they legitimately need to see across accounts. Each of those is a normal engineering necessity, and each is a path around the control.

None of this makes row-level security bad advice. It makes it a mitigation rather than a boundary.

It reduces how often a mistake becomes a leak. It does not stop the table being shared.

Shared Tenancy

Isolation by Correctness

  • One database, everybody's rows
  • Separation enforced per query
  • Admin and reporting paths bypass it
  • One missing condition reaches everyone
  • You cannot inspect it or audit it
BOUNDARY: LOGICAL
Per-Client Isolation

Isolation by Structure

  • Separate application, separate database
  • Separate credentials and keys
  • No cross-account query is expressible
  • A mistake reaches one business — yours
  • Export and shutdown are yours to order
BOUNDARY: PHYSICAL
03 Blast Radius

Why the Difference Only Shows Up on the Worst Day

On an ordinary day these two architectures are indistinguishable to the person using them. The screens look the same. The data loads. Nobody thinks about tables.

The difference is entirely about what happens when something goes wrong, and it shows up as three questions you will suddenly care about very much. Whose data was exposed — just yours, or everyone's? Can anyone tell you — is there a log that distinguishes your records from the rest, or does the honest answer become "we cannot rule it out"? And can you do anything about it — can you rotate your own credentials, pull your own export, and shut your own instance down, or do you wait for a vendor's status page?

In a shared system the answers are largely out of your hands, which is why breach notifications from subscription software read the way they do. They arrive as email, they are vague about scope, and there is nothing for the customer to do but wait. That is not evasiveness. It is a structural consequence: when a boundary is logical rather than physical, establishing exactly what was on the wrong side of it after the fact is genuinely hard.

04 The Trade

Why Almost Nobody Ships Isolation

It is more expensive per customer, and that is the whole reason. Hundreds of separate deployments mean hundreds of databases to back up, hundreds of applications to patch, and hundreds of things to monitor. A vendor serving a hundred thousand small accounts at a low monthly price genuinely cannot do this, and it would be dishonest to pretend the economics are not real.

What changed is the automation. Provisioning, deploying, patching and monitoring an isolated stack is now something a well-built pipeline does rather than something a person does, and when the marginal cost of one more deployment falls far enough, the trade stops being obvious. It is still a real cost. It is just no longer a prohibitive one for the systems that hold a business's customer records.

The question was never whether isolation is better. It was whether it was affordable — and that answer moved.

05 The Alternative

What Per-Client Isolation Looks Like in Practice

Every Araptus Doon deployment is its own application with its own database and its own credentials. There is no shared table, no tenant column, and no query anybody could write — correctly or otherwise — that returns another business's records, because those records are not in the same system to be returned.

That does not make it invulnerable, and the same honesty applies here as anywhere: an isolated system can still be misconfigured, its credentials can still be mishandled, and the people with access are still the largest risk in any architecture. What isolation changes is the shape of the worst case. A mistake reaches one business. The logs describe one business. The keys belong to one business, and rotating them is a decision that business gets to make.

It also changes what leaving looks like. When your data is genuinely separate, an export is a copy of your system rather than a filtered extract from someone else's — which is the difference between switching vendors and negotiating with one. That is a security property and a commercial one at the same time, and it is the reason isolation sits under everything we build.

06 Why We're Saying It

We build isolated deployments, so we are not a neutral party and you should weigh this accordingly. We have tried to earn the argument by conceding the parts that cut against us: row-level security is a real control, multi-tenancy is a legitimate design rather than negligence, and isolation costs more — which is precisely why the industry does not do it.

If you are running on shared software today, the useful exercise is not to panic about it. It is to ask your vendor three questions and see how comfortable the answers are: is row-level security enabled on every table, which internal systems bypass it, and in a cross-tenant incident could they tell you specifically whether your records were reached.

The bottom line

There is nothing to leak into when there is nobody else in the database.

Shared software makes isolation a promise. Separate deployments make it a fact about the architecture.