Multi-tenancy is an architecture decision, not a package install
Laravel has excellent packages for tenancy. None of them remove the need to decide how isolated your tenants must be — legally, operationally, and financially.
Three patterns I have shipped
1. Shared schema with `tenant_id` (row-level)
Best for: Many small tenants, similar schemas, cost-sensitive hosting.
Pros: Simple deployments, one migration path, easy cross-tenant admin dashboards.
Cons: One missing where('tenant_id') clause is a data leak. Testing must be obsessive. Noisy neighbors share DB resources.
Laravel tip: Global scopes, middleware that sets tenant context, and policy classes that always resolve tenant before authorization.
2. Separate databases per tenant
Best for: Enterprise clients, regulatory isolation, wildly different data volumes.
Pros: Strong isolation, per-tenant backup/restore, easier "export all your data" compliance stories.
Cons: Migration orchestration across hundreds of DBs, connection pooling complexity, higher infra cost.
Laravel tip: Dynamic connection switching in middleware; never hardcode the default connection in tenant-aware models.
3. Hybrid — shared app, isolated schemas
A middle path for PostgreSQL-heavy stacks. Less common in my PHP work but worth mentioning when schemas diverge per tenant.
What actually breaks in production
- Forgotten tenant scoping in queued jobs (the web request had context; the job did not)
- File storage without tenant prefixes — S3 paths are part of your tenancy model
- Search indexes that aggregate across tenants for admin tools but leak in user-facing APIs
- Billing webhooks that create resources before tenant provisioning finishes
How I choose
| Requirement | Pattern |
|---|---|
| < 500 tenants, SMB market | Shared schema |
| Healthcare / finance with audit demands | Separate databases |
| Need per-tenant schema migrations | Separate DB or schema-per-tenant |
| Fast MVP, refactor later | Shared schema with strict scopes — **but** plan the escape hatch |
The escape hatch
If you start shared, document how you would split a single large tenant into its own database. If you start isolated, document how you would onboard micro-tenants without provisioning overhead.
Multi-tenancy mistakes are migration-shaped. Choose the pattern that matches the worst-case compliance story, not the happiest demo path.