AEM and MariaDB for off-platform storage

Adobe Experience Manager is built around a content repository, but the repository should not become the default home for every data type an implementation needs. Customer profiles, order records, subscription events, telemetry, audit trails, and high-volume transactional data often require relational capabilities that are outside AEM’s core strengths.

MariaDB can provide that external persistence layer while AEM remains responsible for content authoring, delivery, workflows, permissions, and presentation. The result is a split architecture: AEM manages experience content, while MariaDB stores structured operational data through a controlled integration boundary.

This approach requires more than adding a JDBC driver and creating a table. Teams must define ownership, service interfaces, failure behavior, security controls, deployment procedures, and monitoring. When those decisions are made early, off-platform storage can improve scalability without weakening the editorial experience.

Why move selected data outside AEM

AEM’s repository is well suited to pages, assets, components, configurations, and content relationships. It is less suitable for workloads involving frequent updates, complex joins, strict relational constraints, or very large collections of short-lived records. For example, storing every interaction event as repository nodes can increase indexing work and create unnecessary repository growth.

MariaDB offers familiar relational tools: normalized schemas, indexes, constraints, transactions, and SQL reporting. It can support data that changes independently of a publication cycle, such as inventory status or customer consent history. External storage also allows a data team to operate transactional workloads without placing the same pressure on AEM author or publish instances.

The boundary should remain deliberate. AEM should not query MariaDB directly from HTL templates or expose database credentials to rendering code. Instead, application code should call a domain-focused service that hides SQL details and returns a stable model. This separation keeps presentation logic simple and makes future database changes less disruptive.

Integration patterns for AEM applications

A common design uses an OSGi service in AEM as the integration layer. The service obtains a managed connection pool, executes parameterized queries through a repository or data-access component, maps rows into domain objects, and exposes methods to servlets, Sling Models, workflows, or scheduled jobs. This structure gives developers a clear place to handle timeouts, retries, validation, and logging.

For read-heavy use cases, AEM can consume data through an API owned by another platform team. MariaDB then remains behind a REST or GraphQL service rather than being accessed from AEM at all. This model is often preferable when several systems need the same business rules, or when database credentials must be isolated from the CMS runtime.

Asynchronous messaging is another useful option. AEM can publish an event when content changes, while a separate consumer updates MariaDB. Conversely, a MariaDB-backed service can publish changes that AEM consumes for cache invalidation or content enrichment. Events reduce synchronous coupling, although they introduce delivery guarantees, idempotency requirements, and eventual consistency.

The CIRCUIT conference archive reflects the kind of architecture-focused environment where these trade-offs are useful: AEM developers need to connect repository content with services, analytics platforms, and operational systems without treating the CMS as the entire application platform.

Designing the MariaDB data layer

The external schema should reflect business concepts rather than AEM node structures. A product availability record, for instance, may include a product identifier, market, quantity, status, source timestamp, and version number. Copying the repository tree into relational tables usually creates awkward joins and makes the database dependent on AEM implementation details.

Every record that relates to AEM content should use a stable identifier. A content path may be convenient, but paths can change during moves or restructures. A durable content ID, external key, or versioned reference is safer. The integration should also define what happens when referenced content is unpublished, deleted, or moved between environments.

Connection management is a production concern. Use an OSGi-configured data source or connection pool, set a bounded maximum pool size, and tune connection and query timeouts. A pool that is too large can overwhelm MariaDB; one that is too small can cause request queues inside AEM. Credentials belong in protected deployment configuration, never in source code or content packages.

Concern AEM repository MariaDB off-platform store
Best suited for Pages, assets, components, configurations Structured transactions and operational records
Query model JCR-SQL2, queries, repository APIs SQL, joins, constraints, indexes
Update pattern Authoring, activation, repository changes Frequent transactional writes
Scaling focus Content delivery and repository health Connection capacity, query plans, replicas
Data ownership AEM content team Application or data platform team
Typical integration Sling Models, services, workflows JDBC service, API, or messaging layer
Main risk Repository bloat and indexing overhead Coupling, connection exhaustion, schema drift

A migration plan should include schema versioning and backward compatibility. Database migrations can be managed with a controlled tool or deployment process, but they should run separately from content activation. A failed schema migration must not leave AEM partially deployed or unable to render unrelated pages.

Consistency, caching, and failure behavior

External data introduces a consistency model that authors and developers must understand. A page may be published successfully while its related MariaDB update is delayed. If the page requires current data, synchronous calls may be necessary. If a short delay is acceptable, an event-driven process with a visible freshness timestamp can reduce page latency and operational coupling.

Caching is often essential for public delivery. AEM’s dispatcher and CDN can cache rendered responses, while an application-level cache can reduce repeated database reads. Cache keys should include relevant dimensions such as product, locale, market, and customer segment. When MariaDB data changes, the system needs a defined invalidation or expiration strategy.

Failures should produce a controlled experience rather than a stack trace. Set short connection and query timeouts, return a safe fallback for noncritical data, and distinguish unavailable data from an empty result. Retrying every failed request can amplify an outage, so retries should be limited, backoff-based, and reserved for errors that are likely to recover.

Transactions require similar care. A MariaDB transaction cannot automatically include an AEM repository change unless a broader distributed transaction architecture is introduced, which is rarely justified for ordinary integrations. Prefer idempotent operations, durable events, reconciliation jobs, and explicit status fields over assuming that two systems will commit atomically.

Security and operational visibility

Use a dedicated MariaDB account with the smallest practical permissions. A read-only account should serve read paths, while a separate writer account should handle approved mutations. Network access should be restricted to required AEM or integration hosts, and database traffic should use encryption where the deployment environment requires it.

Sensitive values should be excluded from logs and error messages. SQL statements may be logged in sanitized form during troubleshooting, but personal information, tokens, and full request payloads should not appear in ordinary application logs. Input validation and prepared statements protect against injection and reduce accidental query failures.

Monitoring needs to cover both sides of the integration. Track request latency, error rates, timeout counts, pool utilization, active connections, query duration, retry volume, and stale-data age. MariaDB should be monitored for slow queries, lock waits, replication health, storage growth, and failed connections.

AEM administrators can use JMX health checks to expose integration status alongside other runtime indicators. A custom health check might verify that configuration exists and that a lightweight database operation succeeds, while deeper diagnostics remain outside the request path. Health checks should distinguish a degraded dependency from a failed AEM instance.

Testing the integration boundary

Unit tests should cover mapping, validation, error translation, and business rules without requiring a running database. Integration tests can then verify SQL behavior against a controlled MariaDB instance, including indexes, constraints, transaction rollback, and character-set handling. Running these tests in continuous integration catches schema drift before deployment.

Performance testing should resemble real traffic rather than a single successful query. Test concurrent reads, bursts after cache expiry, slow database responses, pool exhaustion, and large result sets. Measure end-to-end AEM response time because a fast SQL query can still produce a slow page if serialization, rendering, or remote calls are inefficient.

Deployment testing should include rollback and recovery. Confirm that an older AEM bundle can operate with the current schema when possible, and verify how queued events are replayed after an outage. Data repair tools should be authenticated, auditable, and safe to run repeatedly.

Practical implementation priorities

  • Define which system owns each field, record lifecycle, and business rule.
  • Keep database access behind OSGi services, APIs, or event consumers rather than presentation code.
  • Use stable identifiers, prepared statements, bounded connection pools, and protected configuration.
  • Document freshness expectations, fallback behavior, retry limits, and reconciliation procedures.
  • Monitor AEM and MariaDB together with shared correlation IDs and actionable alerts.

AEM and MariaDB work well together when each platform has a clear responsibility. AEM can deliver governed, cacheable experiences while MariaDB handles relational records, transactional updates, and operational reporting. The integration becomes maintainable when it is treated as a product boundary with explicit contracts rather than as a shortcut to a database connection.

Teams planning this architecture should begin with one bounded use case, document its ownership and consistency requirements, test its failure modes, and instrument it before expanding the pattern across the platform. Explore the conference resources and technical session archive to continue developing practical AEM integration expertise.