Markdown Editor

Multi-Tenancy Design Template (SaaS)

SaaS tenancy model (silo, pool, bridge), tenant context, data isolation, noisy neighbours, lifecycle, residency, cost per tenant

How to use: Use when designing or revising how a SaaS product serves many tenants. Fill the tenant profile and tenancy requirements first; they decide the model per tier and per layer. The main pitfall is adding tenant context late; make every request, row, event and log tenant-scoped from the start.

Preview

Multi-Tenancy Design: [SaaS product or platform name]

Design document for the multi-tenant architecture of a SaaS product: tenancy model (silo, pool, bridge) and trade-offs, tenant identification and context propagation, data isolation, noisy neighbour controls, tenant onboarding and offboarding, per-tenant configuration and feature flags, security and compliance including data residency, per-tenant observability, cost allocation, scaling and migration between tiers. Based on common SaaS architecture practice. Replace every [bracketed] value and every row marked Example; the examples follow a B2B project management product with about 400 business tenants.

Document control

FieldValue
Document ID[MTD-001]
Product[Name]
Version[0.1]
Status[Draft / In review / Approved / Superseded]
Author(s)[@architect]
Reviewers[@security-architect], [@data-protection-officer], [@sre-lead]
Last updatedYYYY-MM-DD
Classification[Internal / Confidential]
Related[System design], [Security architecture], [ADR on tenancy model], [Cost model]

Approvals

RoleNameDecisionDate
Chief architect[@name][Approved / Changes requested]YYYY-MM-DD
Security[@name][Decision]YYYY-MM-DD
Data protection[@name][Decision]YYYY-MM-DD
SRE / operations[@name][Decision]YYYY-MM-DD

Revision history

VersionDateAuthorChange summary
0.1YYYY-MM-DD[@name]First draft
0.2YYYY-MM-DD[@name]Example: Added bridge model for Enterprise tier after security review
1.0YYYY-MM-DD[@name]Example: Approved

Contents

1. Introduction

1.1 Purpose

This document defines how [Product] serves many customer organisations (tenants) from shared infrastructure while keeping their data, performance and configuration isolated. It is the reference for engineering, security and operations decisions that depend on tenancy.

1.2 Definitions

TermMeaning
TenantA customer organisation with its own users, data and configuration
TierA commercial plan that determines isolation level, quotas and features
Tenant contextThe verified tenant identity attached to a request or message
SiloDedicated resources for one tenant
PoolResources shared by many tenants
BridgeA mix: some layers pooled, others siloed

1.3 Tenant profile

TierTenants (now / in 2 years)Users per tenantData per tenantPrice per monthIsolation expectation
StarterExample: 300 / 2,0005-50< 5 GBUSD 300Logical isolation
BusinessExample: 90 / 40050-1,0005-200 GBUSD 4,500Logical isolation, higher quotas
EnterpriseExample: 10 / 401,000-20,000200 GB-5 TBContractDedicated data store, region choice

2. Tenancy requirements

IDRequirementPriorityVerification
MT-01Example: No request can read or modify another tenant's data, even with an application bug in a queryMustRLS tests; penetration test with cross-tenant attempts
MT-02Example: A single tenant cannot raise p95 latency for others by more than 20%MustLoad test with one tenant at 10x normal traffic
MT-03Example: New Starter or Business tenant is usable within 2 minutes of sign-upMustOnboarding pipeline timing
MT-04Example: Enterprise tenants choose EU or US data residencyMustDeployment configuration audit
MT-05Example: Tenant data fully deleted within 30 days of contract endMustOffboarding job evidence
MT-06Example: Cost per tenant reported monthlyShouldFinance report
MT-07Example: Move a tenant between tiers with < 15 min write downtimeShouldMigration rehearsal
[MT-nn][Requirement][Must / Should / Could][Method]

3. Tenancy model

3.1 Options

DimensionSilo (dedicated per tenant)Pool (shared by all)Bridge (mixed per layer)
Isolation strengthStrongest; separate resourcesLogical only; depends on code and database controlsStrong where siloed, logical elsewhere
Cost per tenantHighest; idle capacity per tenantLowest; high utilisationMedium
Noisy neighbour exposureNone between tenantsHighest; needs quotas and limitsLimited to pooled layers
Operations at scaleMany deployments to upgrade and monitorOne deploymentSeveral, grouped by tier
Onboarding speedMinutes to hours (provisioning)Seconds (a row in a table)Depends on tier
Per-tenant customisationEasyHardMedium
Compliance and residencySimple to proveNeeds per-tenant controls and evidenceSiloed layer covers strict tenants

3.2 Decision

LayerStarterBusinessEnterprise
Edge and API gatewayPoolPoolPool (per-region)
Application servicesPoolPoolPool (per-region)
Primary databaseExample: Pool: shared cluster, row-level securityPool: shared cluster, row-level securitySilo: dedicated database per tenant
Search indexPool, tenant-filteredPool, tenant-filteredSilo index
Object storagePool, tenant prefixPool, tenant prefixSilo bucket with tenant-managed key
Background workersPool, fair queuesPool, fair queuesPool with reserved concurrency

Rationale: [summary and ADR link]. Example: pooled compute keeps Starter unit cost under USD 20 per month; siloed data for Enterprise meets contractual isolation and residency requirements without running a separate application stack per customer (ADR-031).

4. Tenant identification and context propagation

4.1 Identification

ChannelHow the tenant is identifiedVerification
Web appExample: Subdomain acme.example.app resolves to tenantMust match tenant_id claim in the session token
Public APIExample: API key or OAuth client bound to one tenantKey lookup in tenant registry
Webhooks inboundExample: Per-tenant signing secretSignature check
Background jobsTenant ID in job envelopeSet by producer from verified context only

4.2 Context propagation

Tenant context is resolved once at the edge and carried in signed tokens and message headers. The sequence shows a request through to the database.

Rules: [list]. Example: services reject requests without tenant context; the context library sets the database session variable on every connection checkout and clears it on return; events without a tenant_id header are dead-lettered; logs and traces include tenant_id automatically.

5. Data isolation

PatternDescriptionProsConsUsed for
Database per tenantSeparate database or clusterStrong isolation, easy restore per tenantCost, many schemas to migrateExample: Enterprise
Schema per tenantOne database, one schema per tenantModerate isolationCatalogue bloat beyond a few thousand schemasNot used
Shared schema with tenant columnAll rows carry tenant_id; enforced by row-level securityCheapest, simple operationsIsolation depends on policy correctnessExample: Starter, Business

Row-level security example for the pooled database (PostgreSQL syntax):

ALTER TABLE project ENABLE ROW LEVEL SECURITY;
ALTER TABLE project FORCE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON project
  USING (tenant_id = current_setting('app.tenant_id')::uuid)
  WITH CHECK (tenant_id = current_setting('app.tenant_id')::uuid);
StoreIsolation controlSecond line of defence
Example: Primary databaseRow-level security on every tenant tableAutomated test that every table has a policy; application role cannot bypass RLS
Example: CacheKeys prefixed t:{tenant_id}:Cache wrapper refuses keys without prefix
Example: Object storagePrefix per tenant; Enterprise bucket per tenantSigned URLs scoped to prefix
Example: SearchMandatory tenant filter added by query builderIndex alias per tenant for Enterprise
Example: BackupsPool backups encrypted; Enterprise backups per tenantRestore runbook per tenant tested quarterly
Example: Analytics copytenant_id retained; access by roleNo cross-tenant data in customer-facing reports

6. Noisy neighbour controls

ControlStarterBusinessEnterpriseBehaviour when exceeded
API rate limit (token bucket)Example: 20 req/s, burst 40100 req/s, burst 200500 req/s, burst 1,000HTTP 429 with Retry-After
Concurrent background jobs21050 reservedJobs queue; fair scheduler
Storage quota5 GB200 GBContractUploads rejected; admin notified at 80%
Search queries per minute3003,00020,000429; cached results served
Export size per job1 GB20 GB200 GBSplit into parts

Fair scheduling: [describe]. Example: background workers pull from per-tenant queues in weighted round-robin, so a tenant importing a million rows cannot delay notifications for others. Database statement timeout is 5 s for pooled tenants. Heavy tenants are detected when they use more than 5% of pooled capacity for 15 minutes and are flagged for review or tier change.

7. Tenant lifecycle

The state diagram shows the lifecycle of a tenant.

7.1 Onboarding

StepActionAutomated byTarget time
1Example: Create tenant record, tier, regionTenant service< 1 s
2Create identity provider organisation and admin userOnboarding workflow< 10 s
3Pool: seed default data. Silo: provision database from templateWorkflow; infrastructure as code for siloPool < 30 s; silo < 20 min
4Apply tier quotas and feature flagsConfiguration service< 5 s
5Send welcome email; register billingBilling integration< 1 min

7.2 Offboarding

StepActionEvidence
1Example: Offer data export for 30 daysExport job ID
2Disable logins and API keysAudit log entry
3Delete rows (pool) or drop database (silo)Deletion job report
4Delete object storage prefix or bucket; search index entriesStorage inventory diff
5Backups expire under retention policy; Enterprise keys destroyedKey destruction record
6Issue deletion certificate to customerSigned certificate

8. Per-tenant configuration and feature flags

TypeExampleStored inChanged by
Tier entitlementExample: SSO, audit log export, API limitsPlan catalogueBilling change only
Tenant settingExample: Working days, logo, default languageTenant settings tableTenant admin
Release flagExample: new-gantt-view on for 10% of tenantsFeature flag serviceProduct team
Operational overrideExample: Raised rate limit during migrationConfiguration service with expirySRE, with ticket

Rules: flags are evaluated with tenant ID and tier as attributes; every override has an owner and an expiry; entitlement checks run on the server, never only in the client.

9. Security and compliance

TopicDesign
Cross-tenant access testingExample: Automated suite tries every endpoint with a token of tenant A and IDs of tenant B; runs in CI
EncryptionAt rest for all stores; Enterprise may supply its own key for its silo
Data residencyExample: EU and US stacks; tenant region fixed at onboarding; pooled services deployed per region; no replication across regions
Administrative accessSupport staff access a tenant only with a ticket and time-limited grant, logged and visible to the tenant admin
Audit loggingPer-tenant audit log of admin and data export actions; retention per tier
Certifications and contracts[e.g. SOC 2 report, ISO/IEC 27001 certificate, DPA per tenant]
Sub-processorsListed per region; tenants notified of changes

10. Observability per tenant

SignalTenant dimensionNotes
Logstenant_id field on every lineSearchable per tenant; masked personal data
Tracestenant_id span attributeSampling raised for Enterprise
MetricsExample: Tier label on all metrics; tenant_id label only on a small set of usage metricsAvoids high-cardinality series
Usage meterRequests, storage, job seconds per tenant per hourFeeds cost allocation and billing
SLO reportingAvailability and latency per tier; per tenant for EnterpriseMonthly report to Enterprise tenants

11. Cost allocation

The monthly cost attributed to tenant tt is

Ct=Dt+Cpool⋅ut∑k=1Nuk+CfixedNC_t = D_t + C_{\text{pool}} \cdot \frac{u_t}{\sum_{k=1}^{N} u_k} + \frac{C_{\text{fixed}}}{N}

where DtD_t is the cost of resources dedicated to the tenant, CpoolC_{\text{pool}} is the cost of pooled resources, utu_t is the tenant's usage units (for example weighted request and storage units), NN is the number of tenants and CfixedC_{\text{fixed}} is shared platform cost that does not vary with usage.

Example for a Business tenant: Dt=500D_t = 500, Cpool=40,000C_{\text{pool}} = 40{,}000, ut=1,200u_t = 1{,}200 of ∑uk=20,000\sum u_k = 20{,}000 units, Cfixed=12,000C_{\text{fixed}} = 12{,}000 and N=400N = 400: Ct=500+40,000×0.06+30=500+2,400+30=2,930C_t = 500 + 40{,}000 \times 0.06 + 30 = 500 + 2{,}400 + 30 = 2{,}930 USD. At a price of USD 4,500 the gross margin is (4,500−2,930)/4,500≈34.9%(4{,}500 - 2{,}930) / 4{,}500 \approx 34.9\%.

TierTenantsAverage CtC_tAverage priceMargin
StarterExample: 3004530085%
Business902,1004,50053%
Enterprise1021,00038,00045%
[Tier][n][Cost][Price][%]

12. Scaling

LayerScaling approachTriggerLimit per unit
Application servicesExample: Horizontal autoscalingCPU > 60% or p95 > 300 msn/a
Pooled databaseExample: Shards (cells) of up to 500 tenants each; tenant-to-cell map in registryCell at 70% CPU or 2 TB500 tenants or 2 TB
Siloed databasesOne per Enterprise tenant; sized per contractTenant growthPer tenant
Event brokerPartitions keyed by tenant IDConsumer lag > 30 s[n] partitions

Cell placement: new tenants go to the least-loaded cell in their region. A cell is a blast-radius boundary: an incident in one cell affects at most its tenants.

13. Migration between tiers

StepPool to silo (upgrade to Enterprise)Rollback
1Example: Provision dedicated database in tenant's regionDelete new database
2Copy tenant rows using logical replication filtered by tenant_idStop replication
3Verify counts and checksums per tablen/a
4Put tenant in read-only mode (target < 15 min)Re-enable writes on pool
5Final sync; switch tenant-to-database mapping in registrySwitch mapping back
6Re-enable writes; monitor for 24 hSwitch back within 24 h if needed
7Delete tenant rows from pool after 14 daysn/a

Downgrades (silo to pool) follow the same steps in reverse and are allowed only at contract renewal.

14. Risks and open questions

IDItemTypeMitigation or next stepOwner
R-01Example: A new table is added without a row-level security policyRiskCI check fails if any table with tenant_id lacks a policy[@name]
R-02Example: One very large Business tenant dominates a cellRiskHeavy-tenant detection; move to own cell[@name]
OQ-01Example: Should Enterprise tenants get dedicated compute in addition to data?QuestionDecide after first three Enterprise contracts[@name]
[ID][Item][Risk / Question][Action][@name]

15. Appendices

15.1 References

ReferenceUse
[Cloud provider SaaS architecture guidance]Silo, pool and bridge vocabulary
PostgreSQL documentation, row security policiesSection 5 example
[Internal ADR on tenancy model]Section 3 decision

15.2 Tenant registry fields

FieldDescription
tenant_idUUID, immutable
tierStarter, Business or Enterprise
regionResidency region, fixed at onboarding
cell_idPooled cell, or null for silo
database_refConnection reference for silo tenants
stateLifecycle state from section 7

Standard and licence note

Based on common SaaS architecture practice for multi-tenant systems, including the widely used silo, pool and bridge tenancy models. Original text written for this collection; examples, limits and figures are illustrative. Template licence: MIT.

Related templates