For AI agents: the complete documentation index is available at https://nhanbe.id.vn/llms.txt, the full documentation bundle is available at https://nhanbe.id.vn/llms-full.txt, and this page is available as Markdown at https://nhanbe.id.vn/aem/advanced/system-design-basics-for-aem-developers.md.

System Design Basics for AEM Developers

31 – System Design Basics for AEM Developers

Target: 3–4 years experienced AEM Developer Covers from your additional list: system design basics — how to structure an open-ended "design a system" answer using the AEM building blocks this repository has already covered in depth. Project domain: a global energy technology company's marketing site.


Before we start — why this isn't a generic system design file

At 3-4 years, an AEM-specific system design question is rarely "design Twitter." It's much more likely to be "how would you architect a multi-country corporate site that needs to launch a campaign simultaneously in twenty markets without falling over" or "how would you let a mobile app and a website share the same content." Those questions have a very specific right shape of answer, and the good news is you already have every building block — this file's job is to teach the shape, not introduce new AEM facts.

The single biggest mistake at this level is answering an AEM system design question with generic distributed-systems vocabulary (load balancers, sharding, message queues) borrowed from a general system design course, without ever mentioning Dispatcher, MSM, or the author/publish split — the exact things that make an AEM answer sound like it came from someone who's actually built one of these. This file is about grounding the generic system design framework in the specific AEM vocabulary you've already earned across files 01, 12, 14, 18, 19, 21, and 24.


1. Introduction

1.1 The framework, in one shape

Every system design answer, AEM or otherwise, follows roughly the same shape, and naming the steps out loud is itself a signal that you know how to structure an open-ended answer rather than free-associate:

  1. Clarify the requirements — functional (what does it do) and non-functional (how fast, how available, how many markets, how much traffic).
  2. Sketch the high-level architecture — the boxes and arrows, at the level file 01's diagrams operate at.
  3. Drill into the parts that matter most for this specific question — don't go deep everywhere; go deep where the interesting trade-offs are.
  4. Name the trade-offs explicitly — every real design choice costs something; saying so is more convincing than pretending there's a free lunch.
  5. Mention how you'd validate it — what would tell you the design was wrong, and how you'd find out before it's expensive to fix.

1.2 The AEM-specific building blocks you already have

Building blockFileWhat it solves in a system design answer
Author / Publish / Dispatcher / CDN01The base topology every AEM answer starts from
MSM (blueprint / live copy)12Multi-site, multi-market content reuse and rollout
Dispatcher caching, CDN layering19Read scalability and global latency
AEM as a Cloud Service (autoscaling, pods)14Elastic scale under variable traffic
Content Fragments / Experience Fragments15, 16Content reuse across channels and pages
Headless delivery (GraphQL, SPA Editor)24Sharing content with non-AEM-rendered channels (mobile apps, other frontends)
QueryBuilder / indexing limits21Where AEM's own search stops being the right tool
Replication / Sling Content Distribution18How content actually reaches every publish instance
Cloud Manager pipelines26How a design actually gets built and shipped safely

The exercise this file trains: given a prompt, pick the right subset of this table and explain why each piece is there, rather than reciting the whole list regardless of the question.

1.3 A worked example, briefly, to set the pattern

Prompt: "How would you support a global product launch that needs the same campaign live in twenty country sites at 9am UTC simultaneously?"

The answer's shape, not yet the full depth (that comes in section 7): one blueprint page built once, live-copied to all twenty country sites via MSM with market-specific overrides where regulation requires them; content authored and reviewed ahead of time on lower environments; a single rollout triggering activation across all copies close to the launch moment; the dispatcher and CDN caching the pages aggressively once live, with a scheduled cache-warming step immediately after activation so the first real visitor in each market isn't the one paying the cold-cache cost. Every piece of that sentence is something files 12, 18, and 19 already taught — this file is about assembling them into one coherent narrative under a single prompt.


2. Core Concepts

2.1 Functional vs. non-functional requirements — and why AEM interviewers listen for the second kind

A functional requirement says what the system does ("editors can create a campaign page"). A non-functional requirement says how well it needs to do it — latency, availability, number of markets, traffic pattern, editorial team size. The non-functional requirements are what actually drive the interesting AEM decisions. "Twenty country sites" pushes you toward MSM. "A launch moment with a traffic spike" pushes you toward dispatcher/CDN cache warming and Cloud Service autoscaling. "A single article needs to appear on the website and inside a mobile app" pushes you toward headless delivery. Asking clarifying questions about these before sketching a diagram is itself part of a strong answer — it shows you're designing for the actual constraint, not a generic template.

2.2 Read-heavy vs. write-heavy, and why AEM's architecture assumes the former

A marketing site is overwhelmingly read-heavy — many visitors reading, a small editorial team writing — which is exactly why AEM's default architecture separates a write-optimised author instance from a read-optimised, cacheable, horizontally-scaled publish tier (file 01), and why the dispatcher/CDN caching layer (file 19) is where most of the actual scaling work happens. A system design answer that reaches for a database-scaling solution to a marketing-site traffic problem is solving the wrong layer — the fix for "the site is slow under load" is almost always caching further up the chain, not scaling the repository itself.

2.3 Content reuse — the AEM-specific version of "don't repeat yourself"

At the system design level, content reuse isn't a code pattern, it's an architectural decision about where a single piece of truth lives and how it reaches every place that needs it:

  • MSM (file 12) — reuse a page's structure and content across sites, with live copies inheriting from a blueprint and picking up updates automatically unless explicitly overridden.
  • Content Fragments (file 15) — reuse a piece of structured content (a product spec, a press release) across multiple pages and, via headless delivery, multiple channels entirely.
  • Experience Fragments (file 16) — reuse a fully composed piece of experience (a promotional banner, a footer) across many pages without re-authoring it each time.

The system design skill: recognising which kind of reuse a requirement actually needs. "The same page structure in twenty languages" is MSM. "The same product spec on the product page, in a comparison table, and in the mobile app" is a Content Fragment. Picking the wrong one produces a design that technically works but fights the platform.

2.4 Where headless delivery changes the shape of the answer

The moment a requirement includes any non-AEM-rendered consumer — a native mobile app, a partner's website, a kiosk — the answer needs file 24's headless delivery model: Content Fragments as the unit of reusable structured content, GraphQL (persisted queries preferred for production traffic) as the delivery mechanism, and a clear line between content authored in AEM and content rendered somewhere else entirely. The system design mistake to avoid here is assuming the website's existing page-rendering pipeline can just be "exposed as an API" — it can't, cleanly; headless delivery is a genuinely different content model, not a different template engine on the same pages.

2.5 Scaling for a traffic spike — the AEM-specific answer, not the generic one

A generic system design course teaches horizontal scaling and load balancers as the answer to a traffic spike. In AEM terms, that maps to a specific, nameable set of mechanisms: the dispatcher's cache absorbing nearly all read traffic before it reaches a publish instance at all (file 19), the CDN absorbing traffic before it reaches the dispatcher, and, on AEM as a Cloud Service, the publish tier autoscaling (file 14) to add capacity for whatever traffic the caching layers don't absorb. The honest, senior-sounding point to make: the best traffic-spike design is one where the origin (AEM itself) barely notices, because caching absorbed almost everything — autoscaling the origin is the fallback for what caching couldn't catch, not the primary defence.

2.6 Consistency and staleness — the trade-off AEM already makes for you

Replication (file 18) and Lucene's asynchronous indexing (file 21) both mean AEM is eventually consistent by design in more than one place: a publish instance doesn't have brand-new content the instant an author activates it (replication takes a moment, and the dispatcher's own cache adds more delay until invalidated), and a query might not reflect content indexed moments ago. A system design answer that promises instantaneous global consistency for an AEM-based system is promising something the platform doesn't provide — the honest, correct answer names the actual staleness window and explains why it's acceptable for a marketing site's requirements (a few seconds to a few minutes of propagation delay is rarely the difference that matters for editorial content, but genuinely matters to call out for something like a stock ticker or a pricing display).

2.7 Search at scale — knowing when AEM's own tools stop being the right answer

File 21 already made the point that Oak's QueryBuilder is built for scoped, editorial-style lookups, not open-ended full-text search at real traffic volume with faceting and relevance tuning. A system design answer for "add search to the site" needs to recognise this fork explicitly: a scoped, low-volume lookup (find pages tagged with a category, for an admin tool) is fine through QueryBuilder; a public-facing, high-traffic, relevance-tuned search experience is a case for indexing content into a dedicated search service (commonly Elasticsearch or a similar engine) fed by AEM's content, rather than querying the repository directly on every visitor search. Saying this distinction out loud is a strong signal — it shows you know AEM's limits, not just its features.


3. Internal Working

3.1 How a multi-market launch actually propagates, end to end

Tracing the worked example from section 1.3 through the actual mechanisms: content is authored on the blueprint, live-copied to each country site (file 12), reviewed and approved on each market's live copy, then activated. Activation triggers Sling Content Distribution / replication (file 18) pushing the content to every publish pod. Each pod's dispatcher cache is empty for that specific page until the first request — or until a deliberate cache-warming step requests it proactively right after activation, which is the practical fix for "the very first real visitor pays the slow, uncached cost."

3.2 How autoscaling actually interacts with the caching layers

On AEM as a Cloud Service, the publish tier can add pods under load (file 14) — but this only helps for the traffic that actually reaches a publish pod, which, with effective dispatcher and CDN caching, should be a small fraction of total visitor traffic. A design that relies on autoscaling instead of caching is scaling the expensive layer to cover for a cheap layer that isn't doing its job.

3.3 Why a headless and a traditional-rendered channel can share content but not a rendering pipeline

A Content Fragment's structured data is channel-agnostic by design (file 15) — it's the same underlying content whether it's rendered into an HTML page via a component or serialised as JSON via GraphQL (file 24). What's genuinely different between the two channels is everything downstream of that content: page composition, component-level presentation logic, caching strategy (dispatcher caching for HTML, persisted-query caching for GraphQL) — which is why "just expose the existing pages as an API" undersells how much actual design work headless delivery requires.


8. Design Sketches

8.1 Multi-market launch, at a glance

flowchart TD Blueprint["Blueprint page\n(authored once)"] -->|MSM live copy| Market1["Country site 1"] Blueprint -->|MSM live copy| Market2["Country site 2"] Blueprint -->|MSM live copy| MarketN["Country site … 20"] Market1 & Market2 & MarketN --> Activation["Single scheduled activation\n(replication to all publish pods)"] Activation --> Warm["Cache-warming pass\n(dispatcher pre-populated per market)"] Warm --> Live["Live traffic hits warm cache,\nnot AEM origin directly"]

8.2 Content shared across a rendered website and a headless app

flowchart TD CF["Content Fragment\n(single source of truth)"] --> WebComp["Website component\n(HTML, dispatcher-cached)"] CF --> GraphQL["Persisted GraphQL query"] GraphQL --> App["Partner mobile app\n(JSON, app-side caching)"]

8.3 When to introduce a dedicated search service

Low-volume, scoped lookup (admin tool, tag filter)
  → QueryBuilder is fine (file 21)

High-volume, public-facing, relevance-tuned search
  → Index content into a dedicated search service
  → Keep it in sync via an event listener or scheduled job
  → Degrade gracefully if that service is unavailable

9. Common Mistakes

MistakeWhy it happensThe actual cost
Answering with generic system design vocabulary and no AEM specificsBorrowed from a general system design courseSounds like you haven't actually built one of these
Reaching for autoscaling before mentioning cachingAutoscaling feels like the "modern" answerSolves the expensive layer instead of the cheap one that should absorb most traffic
Treating twenty independently authored sites as equivalent to MSMNot recognising the reuse pattern the requirement needsQuadratic maintenance cost with no shared update path
Proposing "expose the website as an API" for a headless requirementUnderestimating how different content and presentation areCouples a new channel to old presentation, breaks on redesign
Promising zero-staleness real-time updates without qualificationSounds impressive, isn't examined for costContradicts how replication and caching actually work, and reads as not understanding the platform
Jumping straight to a dedicated search service for a small siteOver-engineering without checking actual scale/requirementsUnnecessary operational complexity for a problem QueryBuilder would have solved
Not asking clarifying questions before sketching an architectureWanting to look decisiveDesigning confidently for the wrong constraint

10. Best Practices

  • Ask about non-functional requirements before sketching anything — traffic pattern, market count, channel count are what actually shape an AEM answer.
  • Reach for caching before autoscaling when the question is about handling more traffic — autoscaling is the fallback for what caching can't absorb, not the primary defence.
  • Match the reuse mechanism to the actual kind of reuse needed — MSM for site structure, Content Fragments for structured content, Experience Fragments for composed experience blocks.
  • Name the staleness window explicitly rather than promising instant consistency — and call out the specific cases (pricing, live events) where that window would actually matter.
  • Introduce a dedicated search service only once QueryBuilder's actual limits (file 21) are the genuine constraint — not by default.
  • Plan for the first-traffic-after-launch problem explicitly — cache warming is a small addition that prevents the worst version of a "successful but briefly slow" launch.
  • State trade-offs out loud, even unprompted — a design presented as free of cost reads as less credible than one with named, deliberate compromises.

11. Debugging Tips

Because this is a design topic rather than a running system, the "debugging" is really about stress-testing a design verbally in an interview:

If you catch yourself saying...Ask yourself...
"This scales infinitely"What's the actual bottleneck, and what does it cost to move it?
"Updates are instant everywhere"What's the real replication/cache-invalidation window, and does it matter for this content?
"We'd just expose the pages as an API"Is this actually a content model problem, not a routing problem?
"We'd add a search service"Does the actual traffic/relevance requirement justify it yet?
"We'd autoscale for the spike"What's absorbing traffic before it reaches AEM at all?

12. Performance Notes

The performance story in an AEM system design answer is almost always about which layer absorbs traffic, not about micro-optimising any single layer. Dispatcher and CDN caching absorbing the overwhelming majority of read traffic is the single biggest lever available, and it costs nothing at request time once warm — which is why it's worth naming first, before autoscaling or any code-level optimisation, in almost any AEM system design answer involving scale.


15. Comparison Tables

MSMContent FragmentsExperience Fragments
ReusesPage structure and content across sitesStructured content across pages/channelsComposed experience blocks across pages
Typical triggerMulti-country/multi-language sitesThe same fact/spec needed in several placesThe same banner/footer needed on many pages
Dispatcher/CDN cachingPublish tier autoscaling
CostNear-zero at request time once warmReal infrastructure cost per added pod
Primary or fallback?Primary — absorbs most trafficFallback for what caching didn't absorb
QueryBuilderDedicated search service
FitsScoped, low-volume, structural lookupsHigh-volume, relevance-tuned, public search
ConsistencyNear-real-time (with async indexing lag)Depends on sync mechanism — usually a similar or larger lag
Traditional page renderingHeadless delivery
ConsumerAEM's own components/HTLAny client — app, partner site, kiosk
Shared unitThe whole pageThe Content Fragment / structured content itself

Next topic

README — the repository index, study order, and 30/60/90-day preparation plan, written last so it reflects the complete, final set of files.


*Topic 31 of the AEM Interview Preparation repository. Teaching style, energy-sector project domain