vishal patel
Applied in productionAdvancedUpdated 2026-09-23

Design: Headless CMS with Branches & Releases

My speciality — a multi-tenant content platform with Git-like branches, scheduled releases, multi-locale publishing and per-item job status.

cmsmulti-tenantbranchingpublishingmongodb

Requirements

  • Tenants (stacks) with content types, entries, assets, locales with fallback, environments (dev/staging/prod).
  • Branches: fork the content model and content, work in isolation, compare and merge back.
  • Releases: bundle entries and assets across locales and deploy them atomically to an environment, now or on a schedule.
  • Enterprise scale: large tenants, big bulk operations, strict RBAC.

High-level design

diagram

Deep dive 1 — Branches

  • Creation: copy-on-create or copy-on-write for the content model and entries. Let the caller choose which environments to clone: omitted means all, [] means none, and a list means only those. Resolve and validate at the API layer so bad input fails early.
  • Compare and merge: diff by UID per item (added / modified / deleted). Merge strategies decide conflicts. Global-field changes affect every content type that embeds them.
  • Merge as a job: large merges run asynchronously. The job API should expose a per-item breakdown (item, change type, strategy applied, status, affected content types). Otherwise users export the whole branch just to see what changed.

Deep dive 2 — Releases and locale fallback

  • If a locale isn't localised, entries fall back to the master locale's content. That's convenient, but it can publish content into a market that was never reviewed.
  • A "Disable fallback publishing" rule has to be enforced server-side in the release service, not only in the UI, because API and CLI users bypass the UI.
  • Choose failure semantics deliberately: synchronous add fails all-or-none and lists offending items; bulk add skips invalid items and adds the rest; a deploy-time check skips items that became invalid after they were added.
  • Reuse the existing status (SKIPPED) and error envelope to keep clients compatible. Leave legacy v1 behaviour unchanged.

Deep dive 3 — Scale and tenancy

  • Every query is tenant- and branch-scoped by construction (repository layer), with compound indexes that start with {stack, branch, …}.
  • Bulk operations are chunked, resumable and idempotent, with per-tenant concurrency caps so one tenant can't starve others.
  • Publishing emits events for webhooks, search indexing and CDN purge (see Event-Driven Architecture).
Where I've used it

I was tech lead on branch-creation environment cloning, branch merge job item details, and cross-locale release items / Disable Fallback Publishing, and I owned platform architecture for Taxonomy RBAC, Variants and Branches Env. See the case studies for the full decision write-ups.

Sources & further learning

Videos, courses, docs and books I recommend for this topic.

Related topics