DBRaven
Pattern · multi tenancy

Tenant Isolation

established

Summary

Partition a multi-tenant system's data and resources such that one tenant's activity, load spikes, or data cannot affect the correctness or performance of other tenants: choosing from a spectrum of isolation models from shared schema through dedicated infrastructure.

Problem

In a multi-tenant system, one tenant consuming disproportionate resources degrades service for all others. Without isolation, a database query from one tenant can evict another's data from the buffer cache, a write burst can saturate WAL, and a schema migration can block all tenants sharing the table.

Description

Multi-tenant SaaS systems host multiple customers on shared infrastructure. Without deliberate isolation, one tenant's high write rate can saturate the shared database, causing query latency spikes for all tenants (noisy neighbor). One tenant's schema migration can lock tables visible to other tenants. A bug in one tenant's query can trigger index scans that exhaust the shared buffer cache.

Isolation models exist on a spectrum of cost vs. isolation strength:

Shared schema (row-level): all tenants in the same tables, with a tenant_id column on every row. Lowest cost; highest noisy neighbor risk. Requires row-level security (RLS) at the database layer. A missing tenant_id filter is a data leak. Correct for small datasets and low-traffic tenants.

Schema-per-tenant: each tenant has a separate PostgreSQL schema (namespace) in the same database. Slightly stronger isolation: a VACUUM on one tenant's tables does not block others. Still shares connection pool, WAL, and buffer cache.

Database-per-tenant: each tenant has a separate database or cluster. Strong isolation: a runaway query on tenant A cannot affect tenant B. Operationally expensive: 1000 tenants = 1000 database instances to maintain, monitor, and patch. Reserved for high-value tenants or regulated industries requiring data residency.

Hybrid (tiered isolation): most tenants on shared schema; large or regulated tenants on dedicated databases. Routing layer maps tenant ID to the correct storage endpoint. This is the common production model for SaaS companies at scale (Notion, Figma, Salesforce, Shopify all use variants of this approach).

Resource isolation: even within a shared schema, quota enforcement (max queries/sec, max connections, max storage GB per tenant) limits a tenant's blast radius.

Row-level security enforces shared-schema isolation at the database layer:

ALTER TABLE documents ENABLE ROW LEVEL SECURITY;

CREATE POLICY tenant_isolation ON documents

USING (tenant_id = current_setting('app.current_tenant')::uuid);

-- set at connection time: SET app.current_tenant = '<tenant_id>';

Schema-per-tenant connection routing sets the search path per connection, for example in SQLAlchemy by listening for the connect event and issuing SET search_path TO {tenant_schema}, public. In a hybrid model, a tenants table records each tenant's tier (shared or dedicated) and connection string, and the request path looks up the tenant's tier to route to the correct connection.

Tradeoffs

Noisy neighbor elimination
+0.7

Tenant A's spike cannot degrade tenant B

Compliance support
+0.6

Database-per-tenant enables data residency and isolation for regulated industries

Schema flexibility
+0.4

Schema-per-tenant allows per-tenant customization without shared-table complexity

Blast radius
+0.6

A misconfigured query for one tenant does not affect others

Operational cost
-0.5

Operational cost scales with tenant count for stronger isolation models

Connection pooling complexity
-0.3

Connection pooling is more complex with schema-per-tenant (different search_path) or database-per-tenant

Per-unit infrastructure overhead
-0.3

Shared infrastructure (monitoring, backups, patching) must be applied per isolated unit

Cross-tenant query cost
-0.3

Cross-tenant queries (analytics, platform-wide aggregations) require fan-out across all tenants

When to use

Serving multiple customers from shared infrastructure (SaaS)

Single-tenant systems do not have the noisy neighbor problem

Enterprise customers have compliance or data residency requirements

Shared schema cannot satisfy regulatory requirements for data isolation; database-per-tenant is required

Tenants have highly variable write rates and a few large tenants dominate usage

A power-law distribution of tenant activity creates severe noisy neighbor risk without isolation

Schema evolution is needed per tenant (custom fields, tenant-specific tables)

Shared schema cannot accommodate per-tenant schema customization without runtime complexity

When not to use

Internal tool serving one organization

Single-tenant architecture; tenant isolation is unnecessary overhead

All tenants are known to have identical, bounded workloads

If workloads are identical and bounded, noisy neighbor risk is low; isolation adds operational cost

Operational Requirements

mandatory

Test RLS policies exhaustively

A bug in an RLS policy is a data leak, not a latency issue.

mandatory

Apply schema-per-tenant migrations to all tenant schemas atomically

A partial migration leaves the system in an inconsistent state.

mandatory

Monitor per-tenant resource usage

Track CPU, connections, storage, and query count to enforce quotas and detect a noisy neighbor before it affects others.

mandatory

Treat the hybrid model's routing table as critical infrastructure

Its availability determines the availability of all tenant data access.

Characteristics

Scales on
Implementation complexitymedium
Operational complexitymedium

Relationships

Complements

shardingdatabase per servicerate limitingbulkhead isolation

Basis

Tenant isolation models are extensively documented in SaaS architecture literature; RLS implementation is in PostgreSQL documentation; hybrid isolation models are discussed in Notion, Shopify, and Salesforce engineering content

Related Architecture Knowledge

Outbound: this entity affects

ComplementsPattern
rate limiting
Grounded

Rate limiting enforces per-tenant quotas at the API level; tenant isolation enforces per-tenant resource boundaries at the database level. Together they provide multi-layered protection against noisy neighbors.

Full relationship →
MitigatesFailure Mode
noisy neighbor
Draft · unverified

Tenant isolation enforces resource boundaries that prevent a single tenant's workload from impacting shared infrastructure used by other tenants.

Full relationship →
MitigatesFailure Mode
tenant noisy neighbor
Grounded

Tenant isolation partitions resources between tenants so that one tenant's workload cannot consume resources allocated to others, eliminating the noisy neighbor problem.

Full relationship →

Inbound: affects this entity

Benefits FromWorkload
marketplace mixed workload
Draft · unverified

Marketplace mixed workloads serving multiple seller accounts benefit from tenant isolation to prevent high-volume sellers from degrading the experience of all other sellers on shared infrastructure.

Full relationship →
SupportsTechnology
postgresql
Grounded

PostgreSQL Row Level Security (RLS) policies enforce tenant isolation at the database layer, ensuring queries from one tenant cannot see or modify another tenant's rows.

Full relationship →

Used In Architecture Scenarios