The Strangler Pattern: A Capability Migration Runbook

Replace legacy capabilities through controlled routing, isolated comparison, explicit write ownership and tested rollback or forward recovery.

trigger="A legacy capability needs replacement while the existing system must continue serving supported users." owner="The migration lead owns the sequence; the service owner authorizes traffic changes and the data owner authorizes write cutover." participants={["Migration lead", "Legacy service owner", "New service owner", "Database operator", "Security reviewer", "On-call operator"]} prerequisites={["A capability boundary and all entry points", "Approved business semantics and recovery objectives", "A controllable routing boundary", "Data synchronization, fencing and reconciliation plans"]} outputs={["Capability and dependency register", "Safe comparison and discrepancy evidence", "Write-ownership and cutover record", "Rollback or fix-forward runbook and retirement evidence"]} doneWhen={["The new capability meets approved business and operating requirements", "All authoritative writes have a known owner", "Recovery works for the current data state", "Legacy dependencies are retired only after an explicit acceptance gate"]} />

Migrate one capability through an observable boundary

The strangler pattern moves capabilities from an existing system to a replacement over time. A routing or application boundary selects which implementation handles a request. Both systems may operate during the transition, so the migration must account for shared state, dependencies and operational cost.

Use this playbook for a capability-level replacement. It does not require microservices, guarantee uninterrupted service or make every rollback a routing toggle. A small system with a well-tested replacement window may not need prolonged coexistence. A system whose calls cannot be intercepted may need preparatory refactoring.

AWS's pattern guidance and Microsoft's architecture guidance describe incremental replacement and its constraints. This runbook adds the operating gates that must be adapted to your environment.

1. Choose a capability with a defensible boundary

The migration lead maps users, APIs, jobs, events, direct database access, reports and external integrations that reach the capability. Include administrative and support paths. HTTP traffic alone may not reveal a scheduled job that still changes the same records.

Select the first capability using business value, coupling, data risk and observability. A “leaf” operation is not automatically harmless: an email generator can disclose data or send duplicate messages. A read can expose another tenant's information or serve an incorrect financial balance.

Capability / business owner / migration lead:
Supported users and entry points:
Business invariants and intentional behavior changes:
Data read, written and exported:
Background jobs and external side effects:
Dependencies and direct legacy access:
Current authority and proposed authority:
Recovery objectives and irreversible actions:
Acceptance evidence and retirement conditions:

Gate: both service owners agree what is inside the increment and what remains in the legacy system. If a transaction crosses the boundary without a defined consistency model, narrow the increment or resolve that coupling first.

2. Introduce routing without changing business behavior

Initially route the scoped traffic to the legacy implementation. Measure status, latency, errors, request identity and downstream effects. Test path rewriting, headers, authentication context, retries, timeouts and connection behavior. A facade can introduce a new failure point even when it forwards requests unchanged.

"type": "svg-architecture", "title": "Route each capability to its selected implementation", "nodes": [ ], "links": [ ], "caption": "The router selects one authoritative implementation for the scoped operation. The diagram does not imply dual writes. Synchronization and authority changes follow the separate data-state gates below." }} />

Choose a gateway, application adapter or message-routing boundary that can express the required semantics. Do not introduce a service mesh solely to obtain a traffic percentage. A connection pooler or database proxy does not automatically understand business ownership or safely split SQL writes.

Keep routing configuration versioned, authorized and observable. Select cohorts consistently for transactions or sessions that require affinity. Randomly splitting related requests can send one business operation through incompatible implementations.

Gate: the routing layer preserves the current contract and its own failure/recovery path has been exercised.

3. Define business equivalence before shadowing

The product owner writes the invariants: permitted access, money and quantity calculations, state transitions, idempotency, ordering and external effects. Record intentional changes separately. The legacy behavior is evidence, not an unquestionable specification.

| Difference found | Owner decision | Required evidence | |---|---|---| | New implementation defect | Fix the replacement | Regression case against the approved contract | | Legacy defect | Approve corrected behavior and customer handling | Product and domain-owner decision | | Intentional requirement change | Compare against the new requirement | Versioned acceptance criteria | | Nondeterministic field or ordering | Normalize only the approved variation | Comparator rule and retained diagnostic context | | Data freshness or replication lag | Assess against the freshness requirement | Source position and timing | | Unknown difference | Hold promotion | Investigation owner and disposition |

Do not use one aggregate match percentage to hide an authorization failure or incorrect monetary result. Choose risk-specific gates and representative scenarios. Compare performance against the service objective and demand, not a universal percentage of legacy latency.

4. Run comparison without reproducing production effects

The test owner defines what shadow traffic may do. Read-only comparison can still disclose sensitive data, consume shared capacity or trigger downstream behavior. An asynchronous copy can still overload a dependency.

Use a restricted identity and an isolated destination for shadow writes. Suppress email, payments, webhooks and other external effects, or replace them with verified test adapters. Remove unnecessary sensitive fields and confirm permission to use the data. Bound traffic, queue size, retention and resource use; stop copying when limits are reached.

Record source request identity, relevant versions and comparison results without logging full sensitive payloads by default. Test duplicate delivery, timeout and partial completion. Compare business outcomes as well as response bodies.

Shadow results do not prove every production behavior. They may miss writes, state transitions, seasonal work, rare permissions and third-party failures. Exercise those cases separately in an authorized environment.

Gate: differences are classified, high-consequence cases have evidence, and the shadow path cannot create an uncontrolled production effect.

5. Keep one authoritative writer during data migration

The database operator defines authority per entity or bounded capability. Avoid independently writing both stores and assuming they will remain consistent. Partial failures, retries and ordering can leave them divergent.

A common approach is a consistent snapshot plus change capture from the authoritative source. Record the snapshot/log position, apply ordering and deduplication rules, handle deletes and schema changes, and validate business invariants as the target catches up. The exact mechanism depends on the stores and transaction boundaries.

For an application that must update its database and publish an event, a transactional outbox can link the business change and publication intent in one local transaction. Consumers must still tolerate repeated delivery. See AWS's transactional-outbox guidance. An outbox does not make two independent databases one atomic transaction.

| Migration state | Authoritative writes | Recovery implication | |---|---|---| | Baseline and target backfill | Legacy only | Route back to legacy if its state remains valid | | Read comparison and read cohort | Legacy only | Restore reads while preserving source write authority | | Write cutover in progress | Fence old writers, reconcile, then enable the new writer | Stop if authority or catch-up evidence is ambiguous | | New system accepting writes | New only for the migrated scope | Legacy needs a tested reverse path before it can resume | | Legacy retired | New only | Recovery uses the new system's tested restore and replay plan |

A timestamp or row count alone cannot establish consistency. Include missing records, updates, deletes, relationships, balances and other domain invariants. Record the reconciliation scope and exceptions.

6. Cut over using evidence, not a fixed traffic ladder

The service owner selects the cohort from business and data boundaries. Some read paths can use a gradual traffic cohort; a transactional write domain may need a coordinated ownership switch. Do not copy a universal rollout percentage or observation duration.

Before switching writes, drain or fence old writers, including scheduled jobs and direct database clients. Confirm the target's agreed catch-up position, compatibility and recovery readiness. Record the moment authority changes. If a source cannot be fenced reliably, the team has not established a safe single-writer cutover.

"type": "flow", "title": "Write ownership changes through explicit gates", "steps": [ ], "caption": "Before new writes, the unchanged source may remain a recovery option. After new writes, failback needs reconciliation or a tested reverse replication path." }} />

Observe customer outcomes, authorization, latency, errors, queue age, duplicate effects and synchronization health. Select an observation window that covers relevant business cycles and delayed processing. Lack of errors in a quiet window is weak evidence.

Gate: the product, service and data owners accept the measured behavior and know what recovery remains possible.

7. Recover according to the current data state

| Failure | Immediate action | Recovery gate | |---|---|---| | Routing or response regression before new writes | Stop expansion and restore the known route | Legacy remains authoritative and compatible | | Shadow side effect or overload | Stop shadow traffic and contain the effect | Exposure and duplicate work assessed | | New writer fails after accepting changes | Fence affected writes and preserve evidence | Reconcile into a valid recovery target or fix forward | | CDC or reconciliation shows divergence | Stop promotion; isolate the disputed records | Cause understood and invariants restored | | External action times out | Mark outcome unknown and query its authority | Confirm effect before retry or compensation |

Do not return writes to a stale legacy store because its process is still running. A reverse path needs compatible schemas, conflict handling, checkpoints, permissions and a rehearsed procedure. If no safe reverse path exists, use fix-forward or the approved restore/replay plan and communicate its recovery limits.

A rollback is not automatically a failed migration. It is a controlled response when an acceptance condition fails. Preserve the evidence and add the discovered case before attempting the next cutover.

8. Retire the old path only after proving it is unused

Check traffic, scheduled work, event consumers, direct database clients, support tools, reports and vendor callbacks. Observe the cycles that can exercise them. A falling request percentage does not prove that all business dependencies have moved.

The owners approve a retirement record covering data retention, recovery access, contracts, credentials, infrastructure and documentation. Remove fallback routing only when its absence is intentional. Archive necessary records under the approved policy and test the new recovery path independently.

Retirement should reduce duplicated cost and operational ambiguity, but no universal number of days determines readiness. Keep each remaining legacy dependency owned with a reason and review date.

9. Run a migration-operator rehearsal before write cutover

Give an operator who did not build the new path a simulated discrepancy. For example, the target shows an updated customer record, the legacy store shows the previous value, and a downstream notification has an unknown result. Provide the normal dashboards, operation records and runbook. Do not provide the diagnosis.

The operator should establish the authoritative writer, locate the relevant source and target versions, identify the last applied change position, determine whether the notification completed, and select a safe containment step. They should not repair the case by editing both databases or replaying the notification blindly.

Observe where the runbook depends on private knowledge. Missing stable identifiers, inconsistent timestamps, unavailable audit records or unclear ownership can make an otherwise sound migration unrecoverable. Add the discovered evidence and access needs before production cutover.

Repeat the exercise with the old route unavailable. A strangler facade can become a new single point of failure if every path depends on it. Confirm whether existing workloads continue, how operators reach the authoritative service, and which emergency route preserves authentication, authorization and audit controls.

End the rehearsal by reconciling temporary changes. Remove test credentials, restore routing, close synthetic operations, and record the exact recovery boundary demonstrated. The operator and data owner sign off separately because service availability and data correctness are distinct outcomes.

10. Manage the migration as a portfolio of temporary obligations

Maintain an obligation register for every coexistence component: route, adapter, duplicated topic, copied data set, comparison job, compatibility code, flag, credential and special support procedure. Record its purpose, owner, consumers, operating cost, security exposure, retirement evidence and next review trigger.

Review the register during every migration phase. A temporary component can outlive the assumption that created it. An adapter may become a hidden public contract. A duplicate topic may gain a new consumer. A comparison database may retain sensitive data beyond its approved window. Treat these as architecture and governance changes, not harmless leftovers.

Budget the parallel period explicitly. Include duplicated infrastructure, data transfer, reconciliation, support, additional alerts and incident complexity. A slower cutover may reduce transition risk but increase coexistence cost and exposure. A faster cutover may leave too little evidence. The decision owner balances those costs for the specific capability.

Use retirement gates, not a target date alone. Evidence may include consumer acknowledgement, zero usage across relevant cycles, completed data reconciliation, supported recovery without the legacy path, closed retention obligations and removal of old authority. If one obligation remains, keep it visible rather than declaring the whole migration finished.

At program review, report capabilities accepted, obligations opened and obligations closed. Counting only migrated endpoints rewards starting new transitions while leaving costly dual operation unresolved.

Define support during coexistence

Publish which team owns an incident for the facade, legacy path, new path, replication and comparison tooling. A user-visible failure may cross all five. The incident coordinator needs one escalation map and authority to stop routing or writes without negotiating ownership during the event.

Keep alerts tied to actionable symptoms: routing errors, comparison backlog, change-capture lag, reconciliation exceptions, conflicting writer evidence and failed external-effect checks. Do not page on every expected difference or migration batch completion. Separate diagnostic telemetry from conditions requiring immediate containment.

Support tools must respect the same tenant, object and action authorization as the product path. Temporary migration consoles, replay endpoints and database credentials can bypass otherwise sound controls. Inventory them, restrict access, record actions and remove them at the corresponding retirement gate.

During handoff, a second operator should identify the authoritative writer, stop a cohort, inspect a discrepancy and describe recovery after new writes. If that exercise depends on the migration authors, the coexistence phase remains operationally fragile.

Repeat the complete operational handoff after every meaningful version or routing change. Coexistence procedures decay quickly when components, owners, provider behavior or data semantics change, so retain the complete, dated, reviewed, explicitly owned operational validation evidence with the final cutover record.

Cutover record and acceptance checklist

Capability / cohort / change ID:
Routing, application and schema versions:
Business invariants and accepted differences:
Authoritative writer before and after:
Snapshot/log positions and reconciliation evidence:
Old-writer fencing evidence:
Cutover owner, time and stop conditions:
External effects and unknown-outcome reconciliation:
Safe rollback boundary or fix-forward plan:
Observation results and acceptance owners:
Retirement dependencies, retention and recovery evidence:

"All entry points and side effects are mapped", "Routing preserves the existing contract before replacement", "Comparison uses approved semantics rather than blind byte parity", "Shadow traffic has isolated effects, data controls and load limits", "Snapshot, change capture and reconciliation handle updates and deletes", "Write authority and fencing are explicit at cutover", "Recovery after new writes is rehearsed or its limits are accepted", "Legacy retirement follows dependency and retention evidence" ]} />

Limitations and next step

Coexistence adds cost and complexity. The pattern may be unsuitable when a boundary cannot be controlled or the old system cannot remain supported. It does not remove the need for domain expertise, contractual review or data-recovery testing.

Use platform modernization to review a specific capability record and its write-ownership plan. Broader program sequencing belongs in the platform migration playbook.

Primary references