Multi-tenancy in Laravel: separate database vs tenant column
Planning a multi-tenant SaaS on Laravel. The main architectural decision is whether to use one DB with a tenant_id column on every table or separate databases per tenant.
Building for 50-500 tenants initially, potentially 10k+.
Single DB with tenant column: simpler, cheaper, easier to migrate schema across all tenants at once. Main risks: data leakage if you forget a where clause, noisy neighbor, harder to give tenants their data export.
Separate DB per tenant: stronger isolation, easy per-tenant backup and export, noisy neighbor problem gone. Main costs: running migrations across thousands of DBs is slow and complex. We use Tenancy for Laravel (stancl/tenancy) which handles this.
At 50 tenants either works. At 10k+ tenants separate DBs become operationally heavy. Consider a hybrid: shared DB for small/trial tenants, dedicated DB for enterprise customers.
Global scopes on a Tenant model can enforce tenant_id filtering automatically in the single-DB approach. The risk is that global scopes can be bypassed with withoutGlobalScopes(). Requires discipline to not accidentally bypass.
Row-level security in PostgreSQL gives you the isolation of separate tables with the manageability of a single DB. Not available in MySQL/MariaDB. Worth considering if you have flexibility on DB choice.
We went single DB, 200 tenants. The global scope approach works but we had two data leakage incidents in two years where someone bypassed it for a query optimization. Now we have integration tests that verify tenant isolation for every endpoint.
```php blocks are runnable.