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.