System Design FAQ: Top Questions
49. How would you design a Multi-Tenant SaaS Application?
A Multi-Tenant SaaS architecture serves multiple customers (tenants) from a single codebase while securely isolating their data and configurations. Design choices affect performance, scalability, isolation, and cost.
📋 Functional Requirements
- Serve many tenants using one app deployment
- Isolate tenant data securely
- Support tenant-specific configuration and features
- Enable billing and monitoring per tenant
📦 Non-Functional Requirements
- Strong data security and access control
- Scalable to thousands of tenants
- Per-tenant observability and SLAs
🏗️ Tenant Isolation Strategies
- Shared DB, Shared Schema: One DB, tenant_id column in all tables
- Shared DB, Separate Schemas: Schema per tenant, e.g.,
tenant123.users
- Dedicated DB per Tenant: Full DB isolation (best for compliance-heavy apps)
🗄️ Example Table with Tenant Column
CREATE TABLE invoices (
id UUID PRIMARY KEY,
tenant_id UUID NOT NULL,
customer_name TEXT,
amount NUMERIC,
issued_on DATE
);
🔐 Enforcing Isolation with Row-Level Security (PostgreSQL)
ALTER TABLE invoices ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON invoices
USING (tenant_id = current_setting('app.current_tenant')::UUID);
🔧 Configuration per Tenant (JSONB Profile)
CREATE TABLE tenant_profiles (
tenant_id UUID PRIMARY KEY,
config JSONB -- e.g., {"feature_x": true, "theme": "dark"}
);
📦 Billing/Metrics Isolation
- Track API usage, logins, and storage per tenant
- Store metrics in Prometheus with tenant label
🌐 Auth Multi-Tenant Middleware Example
// Express.js middleware
app.use((req, res, next) => {
const token = req.headers["authorization"];
const decoded = decodeJwt(token);
req.tenant_id = decoded.tenant_id;
process.env["APP_CURRENT_TENANT"] = decoded.tenant_id;
next();
});
📈 Observability
- Latency/error rate per tenant
- Isolated dashboards per team or org
- Per-tenant alerts and SLA monitors
🧰 Tools/Infra Used
- DB: PostgreSQL, CockroachDB (multi-region)
- Monitoring: Prometheus + Grafana with tenant label
- Feature Toggles: Flags stored in JSONB or LaunchDarkly
📌 Final Insight
Multi-tenancy architecture decisions impact everything from billing to security. Start with shared DB + tenant ID for MVP, then migrate toward schema or DB isolation as scale and compliance demands increase.