Three models, three failure modes
When building multi-tenant systems, you pick your isolation model early and live with it. Here is an analysis of Database-per-tenant, Schema-per-tenant, and Row-level security.
When building multi-tenant systems, you pick your isolation model early and live with it. The three common approaches:
Database-per-tenant: Strongest isolation. Falls apart operationally — connection pools don't scale beyond a few hundred tenants, migrations become a distributed systems problem, monitoring overhead is O(n tenants).
Schema-per-tenant: Better operationally. Postgres connections can be pointed at the right schema with SET search_path. Breaks down around 500 schemas due to catalog bloat, and shared Postgres processes still see all schema names.
Row-level security (RLS): Single schema, single connection pool. Isolation enforced at the database kernel level — even buggy application code can't read another tenant's data.
Tags
Related Blogs
Multi-tenant Postgres without performance cliffs — why I chose RLS
Schema-per-tenant falls apart at 500+ tenants. Database-per-tenant is operationally unsustainable. Row-level security gives you strong isolation with a single connection pool. Here's exactly how.
Stop Using UUIDv4 for Database Primary Keys
UUIDv4 is completely random. Storing completely random data in a B-Tree index causes page fragmentation and kills insert performance.
Migrating from TanStack Start to Next.js App Router: An Architecture Post-Mortem
A deep dive into why we moved our entire CMS away from Vite SSR and TanStack Router, the performance implications of Server Components, and the hydration traps we had to fix.