It is not primarily a database question

Tenancy looks like a storage decision and behaves like a product decision. It sets what you can promise about isolation, how you deploy changes, how you price, and what a large customer can demand of you later.

Shared everything is simplest and least forgiving

One database with a tenant column is the easiest to build and operate, and every query is one missing filter away from showing one customer another’s data. Enforcing the boundary at the data layer rather than in application code is what makes it survivable.

In a shared schema, a forgotten filter is not a bug. It’s a breach.

Isolated storage is safer and heavier

Separate databases per customer make isolation structural and make migrations, backups, and deploys N times the work. It is the right answer when customers contractually require it, and expensive when chosen for comfort.

The pattern that usually wins

Shared infrastructure with isolation enforced at the data layer, plus the ability to move a specific customer to their own instance if a contract demands it. That keeps ordinary operation cheap and leaves the escape hatch open.

It decides the shape of your migrations

Changing a schema across a thousand tenants is a very different exercise from changing one, and it must be re-runnable and reconcilable per tenant — the reconciliation-first discipline becomes mandatory rather than advisable.

Retrofitting is the expensive path

Introducing tenancy into a system that assumed one customer touches every query and every table. This belongs in the same category as architecture decisions made for the next 10x — cheap now, structural later.