Course outline

Software Architecture / Evolution: capacity, migration, validation, and review / Lesson 15

Migrate architecture through compatible stages

Use a routing seam, data ownership plan, expand-contract change, and explicit rollback limits for a fictional catalog extraction.

About 4 min readContent reviewed
On this page

Lesson goals

  • Separate traffic migration from data ownership transfer.
  • Define verification gates and rollback behavior after new-format writes.

Find a boundary that can route one capability

A strangler-style migration replaces selected legacy behavior behind a stable entry point while other behavior remains in place. For the workshop catalog, a facade can route read requests to the old or new implementation under an explicit rule. This avoids requiring the whole system to change at once, but the routing layer itself becomes an important dependency. Define its ownership, observability, and failure behavior. Choose a coherent capability with a verifiable contract rather than redirecting arbitrary methods whose hidden shared state still ties them to the old implementation.

Make the current writer unambiguous at every stage

Traffic switching does not transfer data authority automatically. Document which implementation owns catalog writes, how the other obtains a view, and how lag is handled. Uncontrolled dual writes create divergent records and difficult conflict resolution. A one-time backfill also needs a plan for changes occurring during the copy. Use checkpoints, version or sequence evidence, and a reconciliation method suited to the actual store. All migration records here are synthetic design examples; no database copy, credential use, or production routing action is performed.

yaml A migration-stage ownership record
stage: new catalog read path in isolated validation
write_owner: legacy catalog
new_read_source: replicated projection with recorded checkpoint
required_checks: [field parity, authorization parity, freshness bound]
traffic_change: none in this teaching example

The record distinguishes read validation from write ownership. A checkpoint is useful only when its source ordering and completeness semantics are defined by the implementation.

Expand before requiring a new representation

An expand-contract change first allows old and new representations to coexist. For example, add an optional structured location while continuing to support the existing display field, migrate data with verification, update consumers, and remove the old form only after evidence supports retirement. Compatibility must cover old application code reading records written by new code during rollback. A nullable column does not by itself solve semantic migration. Decide the authoritative representation when both fields exist and explain how missing, partial, or contradictory values are handled.

State when rollback stops being a simple switch

Before new writes, reverting a read route may be straightforward if the old source remains current. After new-only data or irreversible effects, rollback may require a forward repair, a compatible reader, or a separately verified data conversion. Record this point before changing ownership. The sample gates focus on evidence rather than arbitrary traffic percentages. A successful health check is insufficient if field meaning, authorization, or state transitions differ. Preserve a stop condition and a named decision owner so migration momentum does not override an observed correctness defect.

text Reviewable migration gates
Gate 1: new reader matches defined legacy behavior on synthetic fixtures.
Gate 2: old reader can interpret every new write representation needed for rollback.
Gate 3: one declared writer owns each catalog record.
Stop: any unexplained authorization or semantic mismatch.
Retire: old path removed only after owned migration evidence is complete.

These gates describe a proposed verification plan. They are not recorded passes, deployment approval, or a claim that the legacy implementation is correct in every respect.

Remove the temporary architecture deliberately

Migration adapters, duplicate representations, compatibility readers, and routing flags have ongoing cost. Assign removal conditions and owners when introducing them. Confirm that infrequent consumers, scheduled work, and recovery procedures no longer depend on the old path before retirement. Update diagrams and operational documents to reflect the final owner and delete obsolete exceptions through the normal change process. A migration is complete when the intended behavior and ownership are established and temporary obligations are resolved, not merely when a new service receives its first request.

Common errors and fixes

Both systems update the same record without a conflict rule.

Why it happens
Traffic migration was confused with shared write ownership.
How to fix it
Declare one writer per stage and define synchronization explicitly.
Prevent it next time
Review ownership before enabling any new write path.

Rollback restores old code that cannot read new data.

Why it happens
Only executable artifacts were included in the rollback plan.
How to fix it
Verify backward reading or define a safe forward-repair route.
Prevent it next time
Test rollback against new-format synthetic records.

Temporary routing remains indefinitely.

Why it happens
No retirement evidence or owner was assigned.
How to fix it
Track consumers and remove the seam after verified migration.
Prevent it next time
Create removal conditions with each temporary component.

Check your understanding

1. Why is comparing only HTTP status codes insufficient for a replacement catalog?

Show worked solution

Both paths can return success while differing in field meaning, visibility policy, sorting, pagination, freshness, or missing-record behavior. Compare the declared contract and representative negative cases, including unauthorized access. A status match proves only one coarse aspect of behavior.

2. A backfill copied all rows at noon. Why might the new view still be incomplete?

Show worked solution

Writes during or after the copy may be missing or applied out of order, and deleted records may remain. Define a consistent snapshot or a change-capture boundary with checkpoints, then reconcile against the authoritative owner. A row count alone does not establish semantic parity or correct ownership.

Key takeaways

  • Migration needs stage-specific ownership and compatible data.
  • Rollback limits and temporary-component retirement are part of the design.

Official references