A high-scale multi-tenant SaaS architecture must simultaneously satisfy two conflicting goals: maximum compute/database utilization for low-tier free users (low COGS) and physical data segregation, custom KMS encryption, and dedicated throughput for six-figure enterprise contracts.
The 3 Multi-Tenant Isolation Models
| Isolation Model | Storage Architecture | Best Fit Customer Tier | Cost per Tenant |
|---|---|---|---|
| Pool (Shared) | Single shared database & tables, filtered by tenant_id + RLS | Starter & Pro tiers (< $500/mo) | Ultra Low ($0.002/mo) |
| Bridge (Schema per Tenant) | Shared PostgreSQL cluster with dedicated schemas (tenant_abc.orders) | Mid-Market Growth ($1,000–$5,000/mo) | Moderate ($2.50/mo) |
| Silo (Dedicated) | Dedicated AWS Aurora database, custom KMS key & isolated VPC | Fortune 500 Enterprise ($50k+/yr) | High ($120/mo + compute) |
Dynamic Tenant Connection Pooling & Sharding
In a hybrid multi-tenant system, application worker pods must dynamically direct queries to the appropriate shared cluster or dedicated enterprise database based on the tenant header:
// tenant-connection-pool.ts - Dynamic Tenant Shard & Isolation Resolver
import { Pool } from "pg";
import Redis from "ioredis";
const redis = new Redis(process.env.REDIS_URL!);
const poolCache = new Map<string, Pool>();
export async function getTenantDatabasePool(tenantId: string): Promise<Pool> {
// 1. Check in-memory pool cache
if (poolCache.has(tenantId)) {
return poolCache.get(tenantId)!;
}
// 2. Fetch tenant tier and connection shard string from Redis routing table
const tenantMetadata = await redis.hgetall(`tenant_config:${tenantId}`);
const isEnterpriseSilo = tenantMetadata.tier === "ENTERPRISE_SILO";
const connectionString = isEnterpriseSilo
? tenantMetadata.dedicatedDbUri
: process.env.SHARED_POOL_DATABASE_URL!;
const pool = new Pool({
connectionString,
max: isEnterpriseSilo ? 30 : 10,
idleTimeoutMillis: 30000,
connectionTimeoutMillis: 2000,
});
poolCache.set(tenantId, pool);
return pool;
}Automated Custom Domain Routing & Edge SSL
Enterprise customers demand white-label custom domains (e.g. app.customerbrand.com). We configure Cloudflare for SaaS or AWS CloudFront with automated SSL cert issuance and Next.js edge middleware that resolves tenant IDs in under 3 milliseconds from edge memory dictionaries.
Defeating the "Noisy Neighbor" Problem
In shared pool databases, an unexpected mass CSV export or automated API script from one customer must never degrade response times for other tenants:
- Redis Sliding-Window Rate Limiting: Enforce strict per-tenant and per-IP requests/second quotas.
- Query Timeouts: Enforce a strict 3,000ms maximum SQL query execution timeout for pool tenants.
- Separate Worker Queues: High-volume webhook processing runs on isolated BullMQ worker queues separated by tier.
Granular Usage Metering & Stripe Billing Integration
Modern SaaS monetization combines base subscriptions with usage-based metering (API requests, storage gigabytes, AI token consumption). Record usage events asynchronously into ClickHouse or PostgreSQL and stream usage summaries to Stripe Billing via webhook automations.
Multi-Tenant SaaS Scaling Checklist
✓ Hybrid Pool-Silo database architecture implemented
✓ Row Level Security (RLS) enforced across all shared tables
✓ Automated wildcard and custom domain SSL provisioning
✓ Multi-tenant sliding window rate limits protect shared pools
✓ Tenant metadata cached in Redis with sub-3ms edge resolution
✓ Asynchronous usage metering tracks billable resource limits
✓ Customer-managed KMS encryption available for enterprise tier
✓ Multi-region read replicas eliminate geographic latency
Scale Your SaaS with Endurance Softwares
We architect high-performance multi-tenant SaaS platforms, custom billing systems, and cloud infrastructures for fast-growing software companies.
Discuss Your SaaS ArchitectureFrequently Asked Questions
How does RLS protect against cross-tenant data leaks?
PostgreSQL evaluates Row Level Security policies at the database engine level before executing any query. Even if application code contains bugs, unauthorized tenant rows cannot be returned.
Can an existing single-tenant app be migrated to multi-tenant?
Yes! Endurance Softwares specializes in adding tenant_id decorators, automating RLS policies, and refactoring schema dependencies without interrupting current users.
What is the maximum number of tenants a single PostgreSQL pool can hold?
Using partition tables and composite indexing on (tenant_id, created_at), a single PostgreSQL cluster can easily support over 100,000 shared tenants before needing physical sharding.