Home Resume
Homeβ€Ί Blogβ€Ί AWS Architecture Series #23 β€” DMS and CDC: What "Ongoing Replication" Does Not Promise…
AWS Architecture AWS Architecture Series

AWS Architecture Series #23 β€” DMS and CDC: What "Ongoing Replication" Does Not Promise

The cutover plan says the target is kept in sync by CDC, so the freeze window is minutes. Nobody wrote down what CDC actually promises, and it promises less than the plan assumes: not real-time, no latency SLA, tables only, and a start point that cannot be moved once the task exists.

Verified against current vendor documentation on 16 August 2026. Pricing, limits and API behaviour were checked against the official docs on that date. Cloud services change fast — if you are reading this much later, treat the specifics as a starting point and re-check the linked sources.

Business Challenge

The migration plan has one sentence that everything else depends on: DMS keeps the target in sync, so the cutover window is minutes, not hours. It is written early, by someone reading a product page, and it is never revisited.

On the night, the application is stopped, the team waits for replication to drain, and the wait does not end when anybody expected. Somebody opens a console to find out how far behind the target is, which is the first time in the project anyone has asked.

1"Ongoing replication" is not "real-time replication"

AWS is unusually direct about this, in a note on the CDC page itself: “AWS DMS CDC does not provide real-time replication.” Latency varies with source workload, network conditions, replication instance resources, target ingestion capacity and data characteristics, and “There are no SLAs for CDC latency.” It “can increase to several minutes or longer”.

That is not a caveat about degraded operation. It is the guarantee. A freeze window sized on the assumption of second-level lag is sized against something AWS never offered, and the number you need — your latency, on your data, under your load — can only come from measurement.

2CDC moves rows, not schemas

A full-load task can migrate views, or a combination of tables and views. A CDC-only task, or a full-load task that starts CDC when it completes, migrates “only tables from the source”.

Most migrations use full load plus CDC, because that is the pattern that keeps the window short. That choice quietly removes views from the migration. The target comes up with every row present and correct, and an application that queries a view fails on something that looks nothing like a data problem.

3The start point is decided once, before you know you needed it

“When the task is created, AWS DMS marks the CDC start point, and it can't be changed. To use a different CDC start point, create a new task.”

This is the parameter people get wrong under pressure, at 2am, having just realised the bulk load finished at a different moment than they assumed. There is no correcting it in place. The only remedy is a new task, which means re-establishing where the change stream should begin — the exact problem you were trying to solve.

4Open transactions fall through the gap

On Oracle, starting a CDC task from an SCN or timestamp means you “miss the results of any open transactions and fail to migrate these results” — transactions that began before the start position and committed after it. From DMS 3.5.1 the openTransactionWindow endpoint setting handles them, by shifting the capture position back by a window you specify in minutes.

Nothing reports the loss. The rows are simply not there, and they belong to long-running transactions — which in most estates means the batch jobs, the ones whose absence surfaces at month end rather than at cutover.

Architecture

DMS reads the source engine's transaction log through that engine's own API. Everything that follows — what can be captured, how you address a point in the stream, what "start here" even means — is inherited from the log, not from DMS.

Diagram: what DMS ongoing replication guarantees -- no latency SLA -- and four omissions that raise no error: views, the immutable start point, open transactions, and two-way replication without conflict resolution

One mechanism per engine, and the differences leak

Oracle uses LogMiner or the binary reader against online or archive redo logs, addressed by SCN. SQL Server uses MS-Replication or MS-CDC and reads the transaction log through fn_dblog() or fn_dump_dblog(), addressed by LSN. MySQL reads row-based binlogs, addressed by file and position. PostgreSQL creates a logical replication slot and reads through the test_decoding plugin.

Each requires source configuration before any of it works — Oracle needs supplemental logging, MySQL needs row-level binary logging — and each imposes its own limits. The clearest is PostgreSQL: it “doesn't support a custom CDC start time”, because the engine has no way to map a timestamp to an LSN the way Oracle and SQL Server can. A runbook written around "start replication from 21:00" is not portable between engines, and the failure appears only when you try it.

Addressing a point in the stream

Three ways to say where CDC begins: a custom start time, which DMS converts to a native point; a native start point stated directly in the engine's own terms; or a checkpoint from a previous task. AWS's own caution is that a timestamp “can indicate multiple native points in the transaction log”, which is why the native form exists.

Checkpoints are the underused one. A running task writes recovery checkpoints, and a checkpoint can start another task at that same position — the supported way to fan a migration out to a second target without re-loading, or to recover a failed task at a known point. Setting TaskRecoveryTableEnabled writes them to an awsdms_txn_state table on the target, which matters because checkpoint information held only by the task “is lost if the task is deleted”.

Bidirectional replication is not multi-master

DMS can replicate A to B and B to A, with LoopbackPreventionSettings stopping each task re-applying the other's changes. AWS states the boundary plainly: it “isn't intended as a full multi-master solution” and “doesn't include conflict detection or resolution”. The intended use is data that is operationally segregated — node A owns its rows and node B never writes them.

Two constraints come with it. Loopback prevention “tracks only data manipulation language (DML) statements”, so DDL will loop unless one task filters it out. And such tasks “don't support committing changes in batches”: BatchApplyEnabled must be false, which removes the main throughput optimisation available to a busy task.

Why This Architecture Holds Up

Every limit above is documented, and not one of them raises an error. That is the property that makes them worth designing around rather than discovering.

A task running eight minutes behind reports the same healthy status as one running eight seconds behind. A task that omitted every view reports success. A task that missed a long-running transaction reports success. The feedback you get is that replication is working — which is true, and not the question you were asking.

The gap is between two readings of the same phrase. "Ongoing replication" is accurate: changes flow continuously. The plan needs something stronger — a bounded, known lag at a specific moment — and that is a property of your workload, measured, not a property of the service.

Key Architecture Decisions

DecisionTake thisBecause
Sizing the freeze window Measure CDC latency under production-like load and size from the observed tail, not the average There is no latency SLA. The only number that means anything is one you produced
Views, sequences, procedures Handle outside CDC — Schema Conversion, or applied by hand and verified A task that starts CDC migrates tables only, and reports success having done so
Choosing the start point Decide before creating the task; prefer a native point or checkpoint over a timestamp It cannot be changed afterwards, and a timestamp can map to several points in the log
Oracle sources Set openTransactionWindow to a window wider than your longest transaction Otherwise transactions open at the start position are silently dropped
Recovering or fanning out Enable TaskRecoveryTableEnabled so checkpoints persist on the target Checkpoint information is lost when the task is deleted
Two-way replication Only where write ownership is genuinely segregated by node No conflict detection or resolution exists; conflicts corrupt rather than fail
Verifying the result Enable data validation, and on both tasks in a bidirectional pair It is the only mechanism that compares source and target rather than reporting task health

Closing Thought

DMS is a good service, and none of this is a criticism of it. The documentation states every limit here plainly, including the sentence most likely to change a migration plan: there are no SLAs for CDC latency.

The failure mode is not the tool. It is that "the target is kept in sync" gets written into a plan as an assumption, and the assumption is never converted into a number. Convert it early — measure the lag, on your data, under load — and the rest of the cutover design follows from something real.

Comments

How was your experience?
Your feedback helps improve this site.
PoorExcellent