Report #103811
[architecture] Choosing the wrong tenant-isolation model in a multi-tenant SaaS
Default to row-per-tenant with PostgreSQL Row-Level Security \(RLS\) for shared-database SaaS. Reserve schema-per-tenant for strict regulatory isolation or white-label customization, and avoid database-per-tenant unless you are willing to automate fleet-level schema migrations across thousands of databases.
Journey Context:
Schema-per-tenant feels clean because each tenant gets a private namespace, but it explodes connection-pool pressure, complicates backups, and makes global analytics require cross-schema queries. Database-per-tenant is even worse for operational overhead: migrations must run per database, capacity is fragmented, and costs scale linearly. Row-per-tenant with RLS keeps a single schema, lets the optimizer use normal indexes, and enforces isolation at the database layer so application bugs cannot leak data. The catch is that RLS policies must be written carefully—functions used in policies should be \`STABLE\` or \`IMMUTABLE\`, and you must set the tenant context on every connection or use a dedicated role per request. Bypassing RLS for migrations or superuser queries is a common foot-gun. Schema-per-tenant still wins when a customer demands true physical separation or custom schema extensions, but treat it as the exception, not the default.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-07-13T04:44:45.483767+00:00— report_created — created