> 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.

# 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 block                             | File   | What it solves in a system design answer                                      |
| ------------------------------------------ | ------ | ----------------------------------------------------------------------------- |
| Author / Publish / Dispatcher / CDN        | 01     | The base topology every AEM answer starts from                                |
| MSM (blueprint / live copy)                | 12     | Multi-site, multi-market content reuse and rollout                            |
| Dispatcher caching, CDN layering           | 19     | Read scalability and global latency                                           |
| AEM as a Cloud Service (autoscaling, pods) | 14     | Elastic scale under variable traffic                                          |
| Content Fragments / Experience Fragments   | 15, 16 | Content reuse across channels and pages                                       |
| Headless delivery (GraphQL, SPA Editor)    | 24     | Sharing content with non-AEM-rendered channels (mobile apps, other frontends) |
| QueryBuilder / indexing limits             | 21     | Where AEM's own search stops being the right tool                             |
| Replication / Sling Content Distribution   | 18     | How content actually reaches every publish instance                           |
| Cloud Manager pipelines                    | 26     | How 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

```text
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

| Mistake                                                              | Why it happens                                              | The actual cost                                                                                    |
| -------------------------------------------------------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| Answering with generic system design vocabulary and no AEM specifics | Borrowed from a general system design course                | Sounds like you haven't actually built one of these                                                |
| Reaching for autoscaling before mentioning caching                   | Autoscaling feels like the "modern" answer                  | Solves the expensive layer instead of the cheap one that should absorb most traffic                |
| Treating twenty independently authored sites as equivalent to MSM    | Not recognising the reuse pattern the requirement needs     | Quadratic maintenance cost with no shared update path                                              |
| Proposing "expose the website as an API" for a headless requirement  | Underestimating how different content and presentation are  | Couples a new channel to old presentation, breaks on redesign                                      |
| Promising zero-staleness real-time updates without qualification     | Sounds impressive, isn't examined for cost                  | Contradicts how replication and caching actually work, and reads as not understanding the platform |
| Jumping straight to a dedicated search service for a small site      | Over-engineering without checking actual scale/requirements | Unnecessary operational complexity for a problem QueryBuilder would have solved                    |
| Not asking clarifying questions before sketching an architecture     | Wanting to look decisive                                    | Designing 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

|                 | **MSM**                                 | **Content Fragments**                       | **Experience Fragments**                    |
| --------------- | --------------------------------------- | ------------------------------------------- | ------------------------------------------- |
| Reuses          | Page structure and content across sites | Structured content across pages/channels    | Composed experience blocks across pages     |
| Typical trigger | Multi-country/multi-language sites      | The same fact/spec needed in several places | The same banner/footer needed on many pages |

|                      | **Dispatcher/CDN caching**          | **Publish tier autoscaling**            |
| -------------------- | ----------------------------------- | --------------------------------------- |
| Cost                 | Near-zero at request time once warm | Real infrastructure cost per added pod  |
| Primary or fallback? | **Primary** — absorbs most traffic  | Fallback for what caching didn't absorb |

|             | **QueryBuilder**                         | **Dedicated search service**                                |
| ----------- | ---------------------------------------- | ----------------------------------------------------------- |
| Fits        | Scoped, low-volume, structural lookups   | High-volume, relevance-tuned, public search                 |
| Consistency | Near-real-time (with async indexing lag) | Depends on sync mechanism — usually a similar or larger lag |

|             | **Traditional page rendering** | **Headless delivery**                            |
| ----------- | ------------------------------ | ------------------------------------------------ |
| Consumer    | AEM's own components/HTL       | Any client — app, partner site, kiosk            |
| Shared unit | The whole page                 | The 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
