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:
- Clarify the requirements — functional (what does it do) and non-functional (how fast, how available, how many markets, how much traffic).
- Sketch the high-level architecture — the boxes and arrows, at the level file 01's diagrams operate at.
- Drill into the parts that matter most for this specific question — don't go deep everywhere; go deep where the interesting trade-offs are.
- Name the trade-offs explicitly — every real design choice costs something; saying so is more convincing than pretending there's a free lunch.
- 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
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
9. Common Mistakes
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:
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
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