---
name: aem-architecture
description: Designs and reviews Adobe Experience Manager solution architecture — AEM as a Cloud Service vs 6.5 trade-offs, delivery model (HTL Sites, headless Content Fragments + GraphQL, hybrid, Edge Delivery Services), Maven archetype modules, repository structure, MSM and translation, templates and policies, assets, integrations, caching, security, environments and sizing. Use this whenever the user asks how to structure an AEM project, whether to go headless or use Edge Delivery Services, compares AEMaaCS with AMS or on-prem, plans multi-site or multi-language rollout with live copies, blueprints or language copies, asks where code or content should live (/apps, /conf, /content, /content/dam, /var), about ui.apps vs ui.content or mutable vs immutable content, or needs an architecture decision record or solution outline for AEM. Also apply it when a single component or integration question hides a platform-level decision such as caching, personalization or authentication.
metadata:
  technology: AEM
  type: architecture
---

# AEM Architecture

AEM architecture is mostly a caching and content-modelling problem wearing a CMS costume. Decide first how every page and API response will be cached at the CDN, how authors will reuse content across sites and languages, and what the platform will not let you do (especially on Cloud Service) — components come last.

## 1. Platform: Cloud Service vs 6.5

| Concern | AEM as a Cloud Service | AEM 6.5 (AMS / on-prem) |
|---|---|---|
| Upgrades | Continuous, automatic; no version pinning | Service packs you schedule and regression-test |
| Code deploy | Cloud Manager pipelines only; `/apps` and `/libs` immutable at runtime | Package Manager, CI of your choice |
| Scaling | Autoscaled publish, Adobe-managed CDN in front | Sized up front; you own CDN and dispatcher fleet |
| Replication | Sling Content Distribution; no custom replication agents | Replication/flush agents you configure |
| Assets | Asset microservices + processing profiles | DAM Update Asset workflow on author |
| Run modes | Fixed: author/publish × dev/stage/prod (+ RDE) | Custom run modes allowed |
| Customisation limits | No long-running jobs on publish, restricted Apache modules, no direct JCR/OS access | Almost anything (and you maintain it) |

Default to Cloud Service for new builds. Choose 6.5 only for a hard constraint (regulatory hosting, unsupported custom Apache/OSGi dependencies, a migration not yet funded) and write that constraint into the ADR. Run the Best Practices Analyzer before any 6.5 → Cloud migration.

## 2. Delivery model (decide per experience, not per company)

| Model | Choose when | Watch out for |
|---|---|---|
| **Traditional Sites (HTL + Core Components)** | Marketing sites, in-context editing, MSM-heavy estates | Front-end team must work inside HTL/clientlibs |
| **Headless (Content Fragments + GraphQL persisted queries)** | Apps, SPAs, kiosks, multiple channels consuming structured content | Use persisted queries (GET, CDN-cacheable), never ad-hoc POST queries in production |
| **Hybrid (Universal Editor on a decoupled front end)** | Own front end but authors need visual editing | Instrumentation effort; the legacy SPA Editor is not the strategic direction |
| **Edge Delivery Services — document authoring** | Speed to market, content in Word/Google Docs, top Lighthouse scores | Different dev model (blocks, Git); limited MSM/workflow semantics |
| **Edge Delivery Services — Universal Editor authoring** | EDS performance with AEM-managed content, structured authoring | Newer capabilities: verify feature parity (MSM, translation) for the brief |

Mixing is fine (EDS marketing site + headless app on the same Content Fragments) — record each experience's model and why.

## 3. Project structure (Maven AEM Project Archetype)

```
core               ← OSGi bundle: Sling Models, services, servlets
ui.apps            ← /apps: components, clientlib output, HTL (immutable)
ui.apps.structure  ← repository roots/filters so packages validate
ui.config          ← OSGi configs in /apps/<proj>/osgiconfig/config.<runmode>
ui.content         ← mutable content: /conf templates & policies, /content seed pages
ui.frontend        ← webpack/Vite build → clientlibs in ui.apps
dispatcher         ← Apache + dispatcher config (flexible mode on Cloud Service)
all                ← container package embedding everything; the deployable
it.tests / ui.tests← HTTP integration tests / Selenium or Cypress UI tests
```

- **Immutable** (`/apps`, `/libs`) and **mutable** (`/content`, `/conf`, `/var`, `/home`) content must be in separate packages; Cloud Service rejects mixed packages.
- Configuration per environment via run-mode folders plus `$[env:NAME]` / `$[secret:NAME]` placeholders — never hostnames or secrets in Git.
- Oak index definitions follow the current Cloud Service index-management rules (versioned `-custom-N` names).

## 4. Repository layout

| Path | Holds | Rule |
|---|---|---|
| `/apps/<proj>` | Components, clientlibs, OSGi config | Code only; never author-editable |
| `/conf/<proj>` | Editable templates, policies, CF models, cloud configs | Owned by template authors; seed via ui.content |
| `/content/<site>` | Pages, organised `/<brand>/<country>/<language>` | Structure drives MSM, URLs and dispatcher invalidation |
| `/content/dam/<proj>` | Assets and Content Fragments | Folder metadata schemas, processing profiles |
| `/content/experience-fragments/<proj>` | Header/footer/promo XFs, mirrored per site/language | Mirror site tree so MSM and language copies work |
| `/var` | Workflow instances, audit, runtime data | Purge policies; never content of record |

## 5. Multi-site and multi-language

- **Blueprint → live copies (MSM)** for shared structure across markets; **language masters → language copies** for translation. Typical tree: `/content/brand/language-masters/en` → `/content/brand/de/de`.
- Decide inheritance granularity up front: which components may break inheritance, and who re-enables it. Uncontrolled cancel-inheritance is the main MSM failure mode.
- Rollout configs: standard for pages, custom only with a documented reason; large rollouts run off-peak.
- Translation via the translation framework with a connector to the TMS; translate Content Fragments and XFs together with pages; UI strings via i18n dictionaries in `/apps`.

## 6. Templates, content types, assets

- **Editable templates + policies** in `/conf`: allowed components, styles (Style System), and image widths per template. Govern who may edit templates; changing a policy changes every page using it.
- **Content Fragments** = structured, channel-neutral data (model-driven, GraphQL). **Experience Fragments** = presentational, reusable layout (HTML, Target offers). Don't use XFs as a data store or CFs as layout.
- **Assets**: AEM Assets with metadata schemas and folder-level processing profiles; **Dynamic Media** (or web-optimized image delivery) for renditions/smart crop instead of generating many static renditions. Plan folder sizes (thousands, not hundreds of thousands, per folder).

## 7. Integrations

- Adobe Analytics/Target via **Tags (Launch)** and the data layer; avoid hardcoded vendor scripts in HTL.
- Commerce through **CIF** (GraphQL to the commerce engine), with product data cached, not copied.
- External APIs through an **OSGi service** with connect/read timeouts, a circuit breaker or fallback, and a short-lived cache; secrets from `$[secret:...]`. Sling Models call the service — never HTTP in HTL.
- Prefer client-side or edge calls for per-user data so the page stays cacheable.

## 8. Caching and personalization

- Layers: **CDN → Dispatcher → Publish**. Target a CDN hit ratio above ~90 % for anonymous traffic; every design decision is checked against it.
- Design URLs for caching: selectors and suffixes over query strings; one canonical URL per representation; no per-user data in HTML.
- Personalization options, in order of preference: client-side (Target / fetch of a small JSON), edge-side, **Sling Dynamic Include** for a fragment, and last, uncached personalised pages.
- Invalidation is by path; content tree design determines blast radius.

## 9. Security

- Authors authenticate via **Adobe IMS** (Cloud Service) or SAML/LDAP (6.5); permissions granted to groups, never users, and managed as code (repoinit) where possible.
- **Closed User Groups** protect publish content, but make it uncacheable at the CDN unless you add permission-sensitive caching — scope CUG areas tightly.
- **Service users** via repoinit + service user mapping; no `loginAdministrative`, no admin sessions.
- Dispatcher filters are allow-lists; `/crx`, `/system/console`, and `.infinity.json` are never reachable on publish.

## 10. Environments and NFRs

- Cloud Service: dev → stage → prod through Cloud Manager, plus **RDE** for fast iteration; stage mirrors prod for load tests.
- Capture NFRs explicitly: peak requests/s, cache hit ratio target, TTFB/LCP budgets, author concurrency, asset volume and ingestion rate, content publish latency, RPO/RTO, locales and sites count.
- Sizing (6.5) follows from uncached request rate, not total traffic; Cloud Service autoscaling still cannot rescue a low hit ratio.

## Deliverable format

Produce an **architecture decision record / solution outline**:

1. **Context** — business goals, channels, sites × languages, traffic and NFR numbers.
2. **Decisions** — one table row each: *decision · options considered · choice · rationale · consequences* (platform, delivery model, MSM model, headless contract, personalization, auth).
3. **Logical architecture** — CDN/dispatcher/author/publish/integrations diagram (text or Mermaid).
4. **Content model** — templates, CF models, XF usage, `/content` and `/content/dam` trees.
5. **Caching plan** — per URL pattern: TTL, invalidation trigger, cacheable yes/no.
6. **Risks and open questions** — with owner and due date.

## Anti-patterns to reject

- Choosing headless "because modern" when authors need page editing and MSM — or HTL when three channels consume the same data.
- Mixing mutable and immutable content in one package; content changes shipped via code deploy.
- Per-user or cookie-dependent HTML on cacheable pages; query-string APIs that bypass cache.
- Ad-hoc GraphQL POST queries in production instead of persisted queries.
- External HTTP calls from Sling Models without timeouts or caching.
- Flat `/content/dam` folders with 100k+ assets; XFs used as data stores.
- Admin sessions, user-level ACLs, secrets in OSGi configs committed to Git.
- Uncontrolled MSM inheritance breaks; custom rollout configs with no owner.
- Assuming 6.5 customisations (replication agents, custom run modes, long-running publish jobs) will lift-and-shift to Cloud Service.
