Part 6 · 1 chapters · ~8 min

Multi-Tenancy Designs

Pooled, bridged and siloed tenancy, row-level security in Postgres, tenant context propagation, noisy-neighbour controls, tenant directories and cells, per-tenant keys and regions, and migrating a tenant between tiers.

9

Isolation enforced in the database

code
ALTER TABLE invoices ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON invoices
  USING (tenant_id = current_setting('app.tenant_id')::uuid);
-- per request, inside the transaction:
SET LOCAL app.tenant_id = '6f1c…';          -- from the authenticated token, never from the request body
SELECT * FROM invoices WHERE status = 'open';  -- RLS adds the tenant filter even if the code forgets it
-- the app role must not be the table owner or BYPASSRLS, or policies are skipped

Cells: at large scale, run many identical copies of the stack (cells), each serving a set of tenants. A bad deploy or a runaway tenant affects one cell. The tenant directory routes each request to its cell; moving a tenant is a data migration between cells.

MULTI-TENANCY MODELS
how tenants share infrastructure
pooledAll tenants in shared tables withtenant_id. Cheapest; isolation bycode and RLS.bridgedSchema per tenant in a shareddatabase. Middle ground;migrations multiply.siloedDatabase or stack per tenant.Strong isolation, highest cost;for big or regulated tenants.tieredPool small tenants, silo largeones: the common real answer.noisy neighboursPer-tenant rate limits, queuefairness and quotas (AlgorithmsP5).routingA tenant directory maps tenant tocell, region and database.
swipe the figure sideways, or tap expand for full screen
1/5
pooled
Every row carries tenant_id; every query filters on it. Postgres row-level security enforces it in the database so a missed WHERE clause cannot leak data.
shared tables + RLScheap, needs discipline