Tenant Isolation
establishedSummary
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
Tenant A's spike cannot degrade tenant B
Database-per-tenant enables data residency and isolation for regulated industries
Schema-per-tenant allows per-tenant customization without shared-table complexity
A misconfigured query for one tenant does not affect others
Operational cost scales with tenant count for stronger isolation models
Connection pooling is more complex with schema-per-tenant (different search_path) or database-per-tenant
Shared infrastructure (monitoring, backups, patching) must be applied per isolated unit
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
Test RLS policies exhaustively
A bug in an RLS policy is a data leak, not a latency issue.
Apply schema-per-tenant migrations to all tenant schemas atomically
A partial migration leaves the system in an inconsistent state.
Monitor per-tenant resource usage
Track CPU, connections, storage, and query count to enforce quotas and detect a noisy neighbor before it affects others.
Treat the hybrid model's routing table as critical infrastructure
Its availability determines the availability of all tenant data access.
Characteristics
Relationships
Complements
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
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 →Tenant isolation enforces resource boundaries that prevent a single tenant's workload from impacting shared infrastructure used by other tenants.
Full relationship →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
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 →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
Multi-Tenant SaaS
A multi-tenant API gateway providing authentication, distributed rate limiting, request routing, payload transformation, and per-tenant usage analytics for API publishers. The hot path: authentication check, rate limit evaluation, and routing decision: must complete in under 1ms using Redis-only data structures to avoid proxying latency dominating upstream service response time. PostgreSQL stores tenant configuration, subscription plans, and API key definitions. Kafka receives API usage events for downstream billing and analytics. Configuration changes (rate limit updates, routing rule edits) must propagate to all gateway replicas without restart.
Multi-Tenant SaaS
A multi-tenant developer tooling platform providing CI/CD pipeline execution, log aggregation, code analysis, and dependency scanning across isolated tenant organizations. Tenant isolation is the primary correctness constraint: a security boundary violation between tenants is a critical incident, not a performance event. PostgreSQL row-level security enforces data isolation; Redis manages job queues and distributed locks; Elasticsearch indexes pipeline log output for search; Kafka delivers webhook events to tenant-registered endpoints; MinIO stores pipeline artifacts. Resource quota enforcement prevents any single tenant's burst from affecting others.