Building Multi-Tenancy Patterns
1. Understanding Tenant Isolation Strategies
| Strategy | Isolation | Cost |
|---|---|---|
| Pool (shared) | Lowest | Lowest |
| Bridge (schema) | Medium | Medium |
| Silo (DB/instance) | Highest | Highest |
| Hybrid | Big tenants → silo, small → pool | — |
2. Implementing Shared Database with Tenant ID
Example: Postgres Row-Level Security
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON orders
USING (tenant_id = current_setting('app.tenant_id')::uuid);
-- per request
SET app.tenant_id = '...';
SELECT * FROM orders; -- filtered automatically
| Pro | Con |
|---|---|
| Cheapest, easy ops | Risk of leakage if tenant filter forgotten |
| Dense packing | Noisy neighbors |
3. Implementing Database per Tenant
| Property | Detail |
|---|---|
| Strong isolation | Crash blast radius = 1 tenant |
| Per-tenant backup/restore | Easy DR for one tenant |
| Cost | High at scale (1000s of DBs) |
| Connection routing | Tenant → DSN map; per-request datasource |
4. Implementing Schema per Tenant
| Property | Detail |
|---|---|
| Postgres schemas | One DB, many namespaces |
| Routing | SET search_path TO tenant_xyz |
| Migrations | Apply to each schema (tooling burden) |
| Limit | ~ thousands of schemas before catalog bloat |
5. Implementing Tenant Context Propagation
| Mechanism | Detail |
|---|---|
| JWT claim | tenant_id in token |
| HTTP header | X-Tenant-Id |
| Server context | ThreadLocal / context.Context (Go) |
| Tracing baggage | Propagate cross-service |
6. Implementing Resource Quotas and Limits
| Resource | Mechanism |
|---|---|
| API calls | Per-tenant rate limiter |
| Storage | Quota in app + DB-level (Postgres tablespace) |
| Compute | K8s ResourceQuota per namespace |
| Concurrency | Bulkhead per tenant |
7. Handling Tenant Data Isolation
| Layer | Practice |
|---|---|
| DB | RLS, separate DB/schema |
| Cache | Key prefix: t:<id>:... |
| Queue | Tenant in message header; per-tenant topics for big ones |
| Encryption | Per-tenant DEK (BYOK option) |
8. Implementing Tenant Configuration
| Mechanism | Detail |
|---|---|
| Override layer | Default → tenant override |
| Storage | tenant_settings table; cache |
| Feature flags | Targeted by tenant id |
9. Understanding Noisy Neighbor Problem
| Mitigation | Detail |
|---|---|
| Per-tenant rate limit | Cap requests/sec |
| Bulkhead | Separate thread pools / connections |
| Fair scheduling | Weighted round-robin |
| Promote heavy tenant | Move to dedicated silo |
10. Implementing Tenant-Specific Features
| Approach | Detail |
|---|---|
| Feature flags by tenant | Plan-tier targeting |
| Plan / entitlement service | Authoritative source |
| UI gating | Hide unavailable features |
| Backend enforce | Always re-check server-side |