February 28, 2025
Multi-Tenancy Architecture: Shared Schema vs Isolated
Multi-tenancy is essential for SaaS. How you implement it affects everything.
The Options
Shared Schema: All tenants in one database, separated by tenant_id column.
Isolated Schema: Each tenant gets their own schema in the database.
Isolated Database: Each tenant gets their own database.
What We Chose: Shared Schema
Why: Simplicity, lower costs, easier maintenance.
Trade-off: Requires careful query filtering. One wrong query could leak data.
The Implementation
Every table has a tenant_id column. Every query includes a tenant filter.
We use middleware to inject tenant context automatically:
@app.before_request
def set_tenant_context():
tenant_id = get_tenant_from_jwt()
g.tenant_id = tenant_id
Every query references g.tenant_id. No direct queries without tenant context.
Security
- Row-level security in Postgres
- Application-level filters as backup
- Audit logs for all queries
- Regular security reviews
When to Use Other Approaches
Isolated Schema: If customers demand data isolation for compliance.
Isolated Database: If you have enterprise customers paying $$$.
For bootstrapped SaaS serving SMEs? Shared schema works fine.
The Risk
Data leakage is possible if you mess up. Test thoroughly. Review every query.
Paranoia is appropriate here.