Multi-Tenant Architecture Patterns

Multi-tenancy decides how content, config, and API access are partitioned across clients, brands, or business units — and which isolation tier you pick sets your caching, deployment, governance, and fetch complexity. This page compares three tiers, their tradeoffs, and the cross-cutting cache and governance controls. Tenant boundaries shape everything downstream in Headless CMS Architecture & Platform Selection, from schema design to CDN strategy.

1. Shared database, shared schema (tenant-ID filtering)

All tenants share tables or collections. Every record carries a tenant_id or site_id, and the API enforces row-level security by injecting a tenant filter into every query. This is the default for SaaS CMS providers and high-volume agency portfolios.

Implementation Blueprint:

YAML
# cms-config.yaml
tenancy:
  mode: shared-schema
  tenant_header: X-Tenant-ID
  fallback_tenant: default
  query_injection: strict
  audit_trail: enabled

Frontend Fetch Pattern:

JavaScript
async function fetchContent(endpoint, tenantId, query) {
  const response = await fetch(endpoint, {
    method: "POST",
    headers: {
      "X-Tenant-ID": tenantId,
      "Content-Type": "application/json",
      "Authorization": `Bearer ${process.env.CMS_TOKEN}`
    },
    body: JSON.stringify(query)
  });
  
  if (!response.ok) throw new Error(`Tenant fetch failed: ${response.status}`);
  return response.json();
}

Caching: Cache keys must vary by tenant. Without Vary: X-Tenant-ID or cache-key normalization, you serve Brand A’s content to Brand B. Use tenant-scoped cache tags (purge:tenant:acme) for granular invalidation that doesn’t flush the whole edge.

Tradeoffs:

  • ✅ Lowest cost, fastest provisioning, unified caching, simple migrations.
  • ❌ Cross-tenant leakage if query injection fails; awkward single-tenant backup/restore; global schema changes hit all tenants at once. See Multi-tenant headless CMS architecture explained for the routing detail.

2. Shared database, isolated schema (per-tenant collections)

Tenants share a database instance but live in separate namespaces, schemas, or collections; the CMS routes to tenant-specific structures at the storage layer. Stronger boundaries, still efficient.

Implementation Blueprint:

JSON
{
  "tenancy": {
    "mode": "isolated-schema",
    "routing_strategy": "path-prefix",
    "tenant_prefix": "/tenants/{tenantId}/api/v1",
    "schema_versioning": "per-tenant"
  }
}

Content modeling: Isolated schemas let tenants diverge without breaking each other. Use shared base types (Hero, Footer) with tenant-specific extensions instead of duplicating models — see Content Modeling Best Practices to avoid schema sprawl. This keeps component libraries consistent while allowing editorial flexibility.

Tradeoffs:

  • ✅ Stronger isolation, per-tenant schema versioning, simpler compliance auditing, less cache collision.
  • ❌ Higher storage overhead, slower onboarding, fragmented caching. Needs careful index management across namespaces as tenant count grows.

3. Fully isolated infrastructure (per-tenant instances)

Each tenant gets a dedicated instance, database, and API endpoint, orchestrated via containers (Kubernetes, Docker) or serverless with independent scaling.

Infrastructure-as-Code Blueprint (Terraform):

HCL
resource "cms_instance" "tenant" {
  for_each = var.tenants
  name     = "cms-${each.key}"
  region   = each.value.region
  db_isolation = "dedicated"
  api_version = "v2"
  tags = {
    tenant    = each.key
    environment = each.value.env
  }
}

API strategy: Isolated endpoints mean frontends juggle multiple base URLs, which reshapes the GraphQL vs REST API Tradeoffs — GraphQL’s single endpoint becomes tenant-specific, needing dynamic resolution at build or runtime. Front it with an API gateway or service mesh to route requests, normalize auth, and aggregate telemetry.

Tradeoffs:

  • ✅ Maximum isolation, independent scaling, predictable SLAs, granular backup/restore.
  • ❌ Highest infrastructure and operational cost, complex CI/CD, fragmented monitoring. The AWS Well-Architected Framework for SaaS covers hardening these pipelines.

Cross-cutting controls

CDN caching

Map tenant boundaries to cache segmentation: Cache-Control: s-maxage=86400, stale-while-revalidate=3600 plus tenant-scoped surrogate keys. See Cloudflare Cache Control Guidelines for edge patterns that prevent cross-tenant poisoning.

DX metrics

Track tenant provisioning time, API latency p95/p99, cache hit ratio, and schema deploy success. Tenant-aware dashboards isolate regressions before they reach a client.

Governance

The tier sets your audit model: shared-schema needs application-level logging, isolated infrastructure enables database-level compliance reporting. Add CI policy checks that validate tenant boundaries before content or schema merges.

Decision matrix

Requirement Recommended Tier
High tenant volume, uniform content models, cost-sensitive Shared Schema
Moderate tenant count, divergent content models, compliance auditing Isolated Schema
Enterprise SLAs, strict data residency, independent scaling Fully Isolated

Pick the tier that matches your operational maturity, governance requirements, and delivery architecture. Multi-tenant design is an evolving contract between infrastructure, content operations, and frontend pipelines, not a one-time config.