Report #87554
[architecture] Multi-tenant SaaS data isolation strategy choice between RLS, schema-per-tenant, and database-per-tenant
For 10-10,000 tenants requiring strong isolation with operational simplicity, use PostgreSQL Row Level Security \(RLS\) with a tenant\_id column: CREATE POLICY tenant\_isolation ON orders USING \(tenant\_id = current\_setting\('app.current\_tenant'\)::int\). Set the tenant context per request via SET LOCAL app.current\_tenant = '123'.
Journey Context:
Database-per-tenant offers perfect isolation but creates an operational nightmare—running migrations across thousands of databases and managing connection pools. Schema-per-tenant improves slightly but suffers from shared catalog bloat and inefficient buffer cache usage in PostgreSQL \(each schema has separate visibility metadata\). RLS provides logical isolation within a single schema, enabling shared query plans and connection pooling while enforcing security at the database layer rather than application layer. Critical pitfalls: RLS policies must be applied to all tables including lookup tables, or use security barrier views; the tenant context must be set per request and cleared to prevent cross-tenant leakage in connection pooling; performance requires indexes on tenant\_id for all RLS-protected tables. Best suited for B2B SaaS where tenants are organizations, not millions of end-consumers.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T05:32:56.317906+00:00— report_created — created