If you're building a multi-tenant SaaS with Laravel, you'll face this decision early: shared database (all tenants in one DB with a tenant_id column) or database-per-tenant (each tenant gets their own database).
After running a database-per-tenant architecture in production for WB-CRM, here's a practical comparison.
Shared Database (Single-DB)
// Every query needs tenant scoping
Lead::where('tenant_id', $currentTenantId)->get();
// Risk: forget the scope → data leak
Lead::all(); // Returns ALL tenants' data!
Pros: Simple migrations, easy cross-tenant queries, lower operational complexity.
Cons: One bug = cross-tenant data exposure. GDPR Art. 17 deletion is complex (cascade through all tables). Hard to offer dedicated instances.
Database-per-Tenant
// stancl/tenancy switches the default DB connection
// No tenant_id needed — the database IS the scope
Lead::all(); // Returns only current tenant's data
Pros: Architecturally impossible to leak data. Trivial backup/restore/deletion per tenant. Can offer dedicated instances.
Cons: Migrations run N times. Cross-tenant queries require connection switching. More complex connection pooling.
The Practical Reality
Migrations: We have ~80 tenant migrations. With 50 tenants, that's 4,000 migration operations per deploy. We parallelize via queue workers:
php artisan tenants:migrate --parallel=4
Central vs. Tenant models:
// Central model — MUST set connection explicitly
class Plan extends Model {
protected $connection = 'central';
}
// Tenant model — NO $connection property (rely on bootstrapper)
class Lead extends Model {
// stancl/tenancy handles connection switching
}
The #1 gotcha: If you put $connection = 'mysql' on a central model instead of $connection = 'central', it will silently query the tenant database when tenancy is initialized.
When to Choose What
| Factor | Shared DB | DB-per-Tenant |
|---|---|---|
| < 100 tenants | Either works | Recommended for B2B |
| GDPR compliance critical | Possible but harder | Recommended |
| Cross-tenant analytics | Easy | Requires extra work |
| Dedicated instances | Not possible | Natural extension |
| Cost | Lower | Slightly higher |
For B2B SaaS in regulated industries (healthcare, finance, legal), database-per-tenant is worth the operational overhead. For B2C with millions of users, shared DB makes more sense.
Built with these patterns: WB-CRM — free CRM for SMBs, hosted in Germany.
Top comments (0)