Photo: Unsplash — to use
Multi-Tenancy: The Foundation of Every SaaS Business
Multi-tenancy — serving multiple customers (tenants) from a single software instance — is what makes SaaS economics work. A well-designed multi-tenant architecture enables 10x more customers per dollar of infrastructure compared to dedicated per-customer deployments. But getting the isolation model wrong causes data leaks, performance degradation, and costly re-architecture.
This guide covers every multi-tenancy design decision you'll face building a SaaS product in 2026.
The Three Multi-Tenancy Models
Model 1: Shared Database, Shared Schema (Pool Model)
All tenants share the same database tables. A tenant_id column on every table distinguishes records.
-- Every table has tenant_id
CREATE TABLE users (
id UUID PRIMARY KEY,
tenant_id UUID NOT NULL REFERENCES tenants(id),
email VARCHAR NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Row-level security enforces isolation
CREATE POLICY tenant_isolation ON users
USING (tenant_id = current_setting('app.tenant_id')::UUID);
Pros: Lowest infrastructure cost, simplest operations, best for high tenant count (1000+)
Cons: Risk of data leakage if query filters missed, noisy neighbor performance impact, compliance challenges (GDPR data deletion is table-scan expensive)
Best for: High-volume SMB SaaS, freemium products, developer tools
Model 2: Shared Database, Separate Schemas (Bridge Model)
Each tenant gets their own PostgreSQL schema with identical table structure.
-- Schema per tenant
CREATE SCHEMA tenant_abc123;
CREATE SCHEMA tenant_xyz789;
-- Tenant routing via search_path
SET search_path TO tenant_abc123;
SELECT * FROM users; -- automatically scoped to tenant
Pros: Natural data isolation, easier GDPR compliance (drop schema), good balance of cost vs. isolation
Cons: Schema migrations must run per-tenant (tooling required), PostgreSQL has practical limits at ~1000 schemas
Best for: Mid-market SaaS with 50–500 tenants, compliance-sensitive industries
Model 3: Separate Databases (Silo Model)
Each tenant gets their own database instance. Used by enterprise SaaS for maximum isolation.
Pros: Complete isolation, no noisy neighbor, easy tenant offboarding, meets strictest compliance requirements
Cons: 10–100x higher infrastructure cost, operational complexity, difficult cross-tenant analytics
Best for: Enterprise SaaS with fewer high-value tenants, regulated industries (healthcare, finance)
Hybrid Architecture: The Practical Choice
Most production SaaS products use a tiered approach:/starter plans in the pool model, pro plans in shared schema, enterprise customers in dedicated databases. This matches data isolation level to willingness to pay.
Tenant Routing: How Requests Reach the Right Data
Subdomain Routing
Each tenant gets a subdomain: acme.yourapp.com. The subdomain is extracted from the request host header and resolved to a tenant_id via lookup table. This is the most common approach.
Path Routing
Tenant identifier in the URL path: yourapp.com/t/acme/dashboard. Simpler SSL setup, but less professional-looking.
JWT-Based Routing
Tenant ID embedded in the authentication JWT. Every API request carries tenant context without URL routing. Best for API-first SaaS products.
Row-Level Security: The Safety Net
PostgreSQL Row-Level Security (RLS) is non-negotiable for shared schema/database models. Even if application code has a bug that omits a WHERE tenant_id = ? filter, RLS at the database level prevents cross-tenant data access.
-- Enable RLS on all tenant tables
ALTER TABLE users ENABLE ROW LEVEL SECURITY;
ALTER TABLE users FORCE ROW LEVEL SECURITY;
-- Policy: users can only see rows for their tenant
CREATE POLICY tenant_isolation ON users
USING (tenant_id = current_setting('app.tenant_id')::UUID);
-- Set tenant context at connection time (middleware)
SET LOCAL app.tenant_id = 'abc123-...';
Schema Migration Strategy for Multi-Tenant
The hardest operational problem in multi-tenant SaaS is running schema migrations across all tenant schemas simultaneously. Solutions:
- Flyway/Liquibase with tenant enumeration — run migrations sequentially per schema
- pg-migrate with tenant loop — custom migration runner iterating over tenant list
- Background migrations — add new column nullable first, backfill asynchronously, add NOT NULL constraint after backfill
Never run a blocking ALTER TABLE on all tenant schemas simultaneously in production — it will cause downtime at scale.
Tenant Isolation at the Application Layer
Defense in depth means enforcing tenant isolation at multiple layers:
- Middleware: Extract and validate tenant ID from every request, set context
- ORM layer: Use tenant-scoped base models that automatically apply tenant filters
- Database layer: Row-level security as the final backstop
- Tests: Automated tests that try cross-tenant data access and verify rejection
File Storage Multi-Tenancy
For S3/GCS file storage, use tenant-prefixed paths: s3://bucket/tenants/{tenant_id}/uploads/{file}. Apply IAM policies or signed URL generation scoped to the tenant prefix. Never allow direct user-supplied paths in S3 operations.
Billing and Plan Enforcement
Multi-tenant SaaS requires usage metering per tenant:
- Track API calls, storage, active users per tenant
- Enforce plan limits at the API middleware layer (return 429 with upgrade CTA)
- Stripe Billing with customer metadata linking Stripe customer to your tenant ID
- Webhooks from Stripe update tenant plan status in your database
Performance: Handling the Noisy Neighbor Problem
In shared database models, one tenant's heavy query can degrade performance for all. Mitigations:
- Query timeouts: Set statement_timeout per tenant tier
- Connection pooling per tenant: PgBouncer with per-tenant pool limits
- Background job queues per tenant: Separate queues for heavy export/import jobs
- Read replicas: Route reporting queries to replicas
Getting Started: Recommended Stack
For a new SaaS product in 2026:
- Database: PostgreSQL with RLS (Supabase for managed)
- Multi-tenant ORM: Prisma with tenant context middleware
- Auth: Clerk or Auth0 with organization/tenant support built-in
- Background jobs: BullMQ with per-tenant queues
- File storage: S3/R2 with tenant-prefixed paths
- Billing: Stripe with customer metadata
Frequently Asked Questions
What is multi-tenancy in SaaS?
Multi-tenancy means a single software instance serves multiple customers (tenants), with each tenant's data isolated from others. It's what makes SaaS cost-effective — shared infrastructure amortized across many customers.
Which multi-tenancy model should I use?
Start with shared database, shared schema (pool model) with Row-Level Security — it's the simplest and most cost-effective. Add schema or database isolation for enterprise customers who require it and are willing to pay for dedicated infrastructure.
How do I prevent cross-tenant data leakage?
Use PostgreSQL Row-Level Security (RLS) as your database-level backstop, tenant-scoped ORM base models at the application layer, JWT-embedded tenant context, and automated security tests that verify cross-tenant requests are rejected.
How should I handle database migrations in multi-tenant SaaS?
Never run blocking migrations on all tenants simultaneously. Use background migrations: add columns as nullable first, backfill asynchronously, then add constraints. For schema-per-tenant, run migrations sequentially with a tenant enumeration loop.
What's the best database for multi-tenant SaaS?
PostgreSQL is the industry standard for multi-tenant SaaS. Its Row-Level Security, schema support, and mature tooling make it ideal. Supabase (managed PostgreSQL) with built-in RLS support is excellent for new projects.
Build Your Multi-Tenant SaaS
We architect and build multi-tenant SaaS products from the ground up — database design, tenant routing, billing integration, and scalable backend infrastructure. Let's discuss your product.