<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Engineering Management on Corebaseit — Design System Engineering · POS · Payments · Security</title><link>https://corebaseit.com/categories/engineering-management/</link><description>Recent content in Engineering Management on Corebaseit — Design System Engineering · POS · Payments · Security</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><managingEditor>contact@corebaseit.com (Vincent Bevia)</managingEditor><webMaster>contact@corebaseit.com (Vincent Bevia)</webMaster><lastBuildDate>Thu, 27 Aug 2026 00:00:00 +0200</lastBuildDate><atom:link href="https://corebaseit.com/categories/engineering-management/index.xml" rel="self" type="application/rss+xml"/><item><title>From Monolith to Microservices: Architecture Is the Destination, Migration Is the Plan</title><link>https://corebaseit.com/corebaseit_posts/monolith-to-microservices-migration/</link><pubDate>Thu, 27 Aug 2026 00:00:00 +0200</pubDate><author>contact@corebaseit.com (Vincent Bevia)</author><guid>https://corebaseit.com/corebaseit_posts/monolith-to-microservices-migration/</guid><description>&lt;img src="https://corebaseit.com/diagrams/monolith-to-microservices-migration.png" alt="Featured image of post From Monolith to Microservices: Architecture Is the Destination, Migration Is the Plan" />&lt;p>A monolith can become difficult to change long before it becomes impossible to run.&lt;/p>
&lt;p>Deployments start affecting unrelated areas. A change in refunds requires regression testing checkout. One database becomes the integration layer between half the system. Teams wait for each other. Releases grow larger, rollback becomes scarier, and nobody is completely sure where one business capability ends and another begins.&lt;/p>
&lt;p>At that point, somebody usually draws this:&lt;/p>
&lt;p style="text-align: center;">
&lt;a href="https://corebaseit.com/diagrams/monolithic1.png" target="_blank" rel="noopener">
&lt;img src="https://corebaseit.com/diagrams/monolithic1.png" alt="From monolithic to microservices 1" style="max-width: 720px; width: 100%; height: auto;" />
&lt;/a>
&lt;/p>
&lt;p>The destination looks simple.&lt;/p>
&lt;p>The migration is not.&lt;/p>
&lt;p>Moving from a monolithic architecture to microservices is not primarily a matter of creating smaller applications. It is a &lt;strong>controlled transfer of responsibility&lt;/strong> across boundaries while the existing system continues serving production traffic.&lt;/p>
&lt;p>That makes it both an architectural problem and a project-management problem.&lt;/p>
&lt;p>A useful migration therefore needs more than a target architecture.&lt;/p>
&lt;p>It needs a path.&lt;/p>
&lt;h2 id="start-with-the-reason-not-microservices">Start with the reason, not microservices
&lt;/h2>&lt;p>Before decomposing anything, ask a more uncomfortable question:&lt;/p>
&lt;blockquote>
&lt;p>What problem are we actually trying to solve?&lt;/p>&lt;/blockquote>
&lt;p>Microservices introduce their own costs: network failures, distributed tracing, eventual consistency, deployment coordination, infrastructure overhead, data ownership problems, versioned contracts, retries, duplicate messages, and substantially more operational surface area.&lt;/p>
&lt;p>If the real problem is simply poor module boundaries inside the codebase, a modular monolith may be the better answer.&lt;/p>
&lt;p>A migration should therefore start with measurable architectural drivers:&lt;/p>
&lt;ul>
&lt;li>independent deployment of high-change capabilities;&lt;/li>
&lt;li>different scaling characteristics;&lt;/li>
&lt;li>clearer team ownership;&lt;/li>
&lt;li>fault isolation;&lt;/li>
&lt;li>regulatory or security boundaries;&lt;/li>
&lt;li>independent technology evolution;&lt;/li>
&lt;li>reducing coupling around specific business capabilities.&lt;/li>
&lt;/ul>
&lt;p>This is where the previous discussion about &lt;a class="link" href="https://corebaseit.com/corebaseit_posts/spike-first-adr-second/" >Spikes and ADRs&lt;/a> becomes useful.&lt;/p>
&lt;p>A Spike can investigate whether extracting a capability actually improves the characteristics we care about.&lt;/p>
&lt;p>An ADR can record why that boundary was selected and which consequences were knowingly accepted.&lt;/p>
&lt;p style="text-align: center;">
&lt;a href="https://corebaseit.com/diagrams/monolithic2.png" target="_blank" rel="noopener">
&lt;img src="https://corebaseit.com/diagrams/monolithic2.png" alt="From monolithic to microservices 2" style="max-width: 40%; width: 100%; height: auto;" />
&lt;/a>
&lt;/p>
&lt;p>The ADR tells us &lt;strong>why&lt;/strong>.&lt;/p>
&lt;p>The migration plan tells us &lt;strong>how and when&lt;/strong>.&lt;/p>
&lt;p>Those are different artifacts.&lt;/p>
&lt;h2 id="do-not-migrate-the-monolith-migrate-a-capability">Do not migrate the monolith. Migrate a capability.
&lt;/h2>&lt;p>Imagine a payment platform containing:&lt;/p>
&lt;p style="text-align: center;">
&lt;a href="https://corebaseit.com/diagrams/monolithic3.png" target="_blank" rel="noopener">
&lt;img src="https://corebaseit.com/diagrams/monolithic3.png" alt="From monolithic to microservices 3" style="max-width: 720px; width: 100%; height: auto;" />
&lt;/a>
&lt;/p>
&lt;p>A dangerous project starts with:&lt;/p>
&lt;blockquote>
&lt;p>We are migrating the monolith to microservices.&lt;/p>&lt;/blockquote>
&lt;p>That scope is enormous and gives the programme very few meaningful intermediate success states.&lt;/p>
&lt;p>A better question is:&lt;/p>
&lt;blockquote>
&lt;p>Which capability should we extract first?&lt;/p>&lt;/blockquote>
&lt;p>Suppose Refunds is selected because it has clear business semantics, changes frequently, integrates with unreliable external providers, and has different scaling and failure characteristics from checkout.&lt;/p>
&lt;p>Now the project becomes much more concrete:&lt;/p>
&lt;p style="text-align: center;">
&lt;a href="https://corebaseit.com/diagrams/monolithic4.png" target="_blank" rel="noopener">
&lt;img src="https://corebaseit.com/diagrams/monolithic4.png" alt="From monolithic to microservices 4" style="max-width: 720px; width: 100%; height: auto;" />
&lt;/a>
&lt;/p>
&lt;p>That is something architecture and delivery teams can actually manage.&lt;/p>
&lt;h2 id="the-target-architecture-is-not-the-migration-architecture">The target architecture is not the migration architecture
&lt;/h2>&lt;p>This distinction is easy to miss.&lt;/p>
&lt;p>The desired end state might be:&lt;/p>
&lt;p style="text-align: center;">
&lt;a href="https://corebaseit.com/diagrams/monolithic5.png" target="_blank" rel="noopener">
&lt;img src="https://corebaseit.com/diagrams/monolithic5.png" alt="From monolithic to microservices 5" style="max-width: 720px; width: 100%; height: auto;" />
&lt;/a>
&lt;/p>
&lt;p>But production cannot teleport from the current state to that diagram.&lt;/p>
&lt;p>For some period of time, the real architecture will look more like this:&lt;/p>
&lt;p style="text-align: center;">
&lt;a href="https://corebaseit.com/diagrams/monolithic6.png" target="_blank" rel="noopener">
&lt;img src="https://corebaseit.com/diagrams/monolithic6.png" alt="From monolithic to microservices 6" style="max-width: 60%; width: 100%; height: auto;" />
&lt;/a>
&lt;/p>
&lt;p>That intermediate state may live for weeks or months.&lt;/p>
&lt;p>It is not temporary clutter to ignore.&lt;/p>
&lt;p>It &lt;strong>is the production architecture&lt;/strong> during the migration.&lt;/p>
&lt;p>And it needs to be designed.&lt;/p>
&lt;h2 id="the-strangler-fig-pattern">The Strangler Fig pattern
&lt;/h2>&lt;p>One of the best-known approaches to incremental replacement is Martin Fowler&amp;rsquo;s &lt;strong>Strangler Fig Application&lt;/strong> pattern.&lt;/p>
&lt;p>Instead of rewriting the entire system and switching everything at once, new functionality gradually grows around the old system.&lt;/p>
&lt;p>Conceptually:&lt;/p>
&lt;p style="text-align: center;">
&lt;a href="https://corebaseit.com/diagrams/monolithic7.png" target="_blank" rel="noopener">
&lt;img src="https://corebaseit.com/diagrams/monolithic7.png" alt="From monolithic to microservices 7" style="max-width: 50%; width: 100%; height: auto;" />
&lt;/a>
&lt;/p>
&lt;p>But the percentages are less important than the principle:&lt;/p>
&lt;blockquote>
&lt;p>Replace capabilities incrementally while keeping the system operational.&lt;/p>&lt;/blockquote>
&lt;p>This creates something extremely valuable in architecture programmes:&lt;/p>
&lt;p>&lt;strong>reversibility.&lt;/strong>&lt;/p>
&lt;p>If the first extraction performs badly, creates unexpected coupling, or proves operationally expensive, the organisation has learned something without betting the entire platform.&lt;/p>
&lt;p>That is architecture behaving like risk management.&lt;/p>
&lt;h2 id="migration-needs-phases">Migration needs phases
&lt;/h2>&lt;p>Large architectural initiatives become much easier to reason about when separated into explicit phases.&lt;/p>
&lt;p>A practical structure might look like this:&lt;/p>
&lt;p style="text-align: center;">
&lt;a href="https://corebaseit.com/diagrams/monolithic8.png" target="_blank" rel="noopener">
&lt;img src="https://corebaseit.com/diagrams/monolithic8.png" alt="From monolithic to microservices 8" style="max-width: 720px; width: 100%; height: auto;" />
&lt;/a>
&lt;/p>
&lt;h3 id="phase-1--discovery">Phase 1 — Discovery
&lt;/h3>&lt;p>Understand why the capability is being extracted.&lt;/p>
&lt;p>Map dependencies.&lt;/p>
&lt;p>Identify database tables, APIs, scheduled jobs, events, operational dashboards, external integrations, and other modules that depend on it.&lt;/p>
&lt;p>Run Spikes where uncertainty is material.&lt;/p>
&lt;p>Produce ADRs for significant decisions.&lt;/p>
&lt;p>The output is not yet a microservice.&lt;/p>
&lt;p>It is &lt;strong>reduced uncertainty&lt;/strong>.&lt;/p>
&lt;h3 id="phase-2--establish-the-boundary">Phase 2 — Establish the boundary
&lt;/h3>&lt;p>Define what the new service owns.&lt;/p>
&lt;p>For Refunds, that might mean:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>Refund Service owns:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>- refund lifecycle
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>- refund state machine
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>- idempotency
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>- provider interaction
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>- retry policy
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>- refund persistence
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>- refund events
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The boundary matters more than the framework.&lt;/p>
&lt;p>A Spring Boot service with the wrong business boundary is still the wrong architecture.&lt;/p>
&lt;h3 id="phase-3--build-alongside-the-monolith">Phase 3 — Build alongside the monolith
&lt;/h3>&lt;p>Do not immediately remove the existing path.&lt;/p>
&lt;p>Create the new service while production continues through the monolith.&lt;/p>
&lt;p style="text-align: center;">
&lt;a href="https://corebaseit.com/diagrams/monolithic9.png" target="_blank" rel="noopener">
&lt;img src="https://corebaseit.com/diagrams/monolithic9.png" alt="From monolithic to microservices 9" style="max-width: 60%; width: 100%; height: auto;" />
&lt;/a>
&lt;/p>
&lt;p>This gives the team somewhere to migrate traffic gradually.&lt;/p>
&lt;h3 id="phase-4--validate-in-parallel">Phase 4 — Validate in parallel
&lt;/h3>&lt;p>Before trusting the new path with all production traffic, compare behaviour.&lt;/p>
&lt;p>Depending on the capability, techniques can include:&lt;/p>
&lt;p style="text-align: center;">
&lt;a href="https://corebaseit.com/diagrams/monolithic10.png" target="_blank" rel="noopener">
&lt;img src="https://corebaseit.com/diagrams/monolithic10.png" alt="From monolithic to microservices 10" style="max-width: 60%; width: 100%; height: auto;" />
&lt;/a>
&lt;/p>
&lt;p>The second path does not necessarily execute external side effects. For payments and refunds, blindly duplicating a production command would obviously be dangerous.&lt;/p>
&lt;p>But calculations, transformations, routing decisions, or state transitions can often be compared safely.&lt;/p>
&lt;p>This turns migration from:&lt;/p>
&lt;blockquote>
&lt;p>We think the new service works.&lt;/p>&lt;/blockquote>
&lt;p>into:&lt;/p>
&lt;blockquote>
&lt;p>Across 1.8 million representative operations, the old and new implementations agreed in 99.99% of the cases, and we understand the remaining differences.&lt;/p>&lt;/blockquote>
&lt;p>That is a much stronger basis for moving traffic.&lt;/p>
&lt;h2 id="move-traffic-not-hope">Move traffic, not hope
&lt;/h2>&lt;p>Eventually the new service must become authoritative.&lt;/p>
&lt;p>Do not think only in terms of deployment.&lt;/p>
&lt;p>Think in terms of &lt;strong>traffic migration&lt;/strong>.&lt;/p>
&lt;p style="text-align: center;">
&lt;a href="https://corebaseit.com/diagrams/monolithic11.png" target="_blank" rel="noopener">
&lt;img src="https://corebaseit.com/diagrams/monolithic1.png" alt="From monolithic to microservices 11" style="max-width: 90%; width: 100%; height: auto;" />
&lt;/a>
&lt;/p>
&lt;p>A migration might progress through controlled stages:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>Stage 1 100% old 0% new
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Stage 2 95% old 5% new
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Stage 3 75% old 25% new
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Stage 4 25% old 75% new
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Stage 5 0% old 100% new
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The exact percentages are implementation details.&lt;/p>
&lt;p>The important part is that each stage has &lt;strong>entry criteria, observations, and rollback conditions&lt;/strong>.&lt;/p>
&lt;p>For example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>Proceed if:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>error rate &amp;lt; threshold
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>p95 latency &amp;lt; threshold
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>duplicate rate = expected
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>reconciliation = clean
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>DLQ growth = normal
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>provider errors = understood
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Architecture has now become measurable.&lt;/p>
&lt;h2 id="data-is-usually-the-hard-part">Data is usually the hard part
&lt;/h2>&lt;p>Extracting Java or TypeScript code into another repository is rarely the hardest part.&lt;/p>
&lt;p>Data ownership is.&lt;/p>
&lt;p>The monolith may currently do this:&lt;/p>
&lt;p style="text-align: center;">
&lt;a href="https://corebaseit.com/diagrams/monolithic12.png" target="_blank" rel="noopener">
&lt;img src="https://corebaseit.com/diagrams/monolithic12.png" alt="From monolithic to microservices 12" style="max-width: 720px; width: 100%; height: auto;" />
&lt;/a>
&lt;/p>
&lt;p>Creating four services that all continue directly accessing those same tables gives us:&lt;/p>
&lt;p style="text-align: center;">
&lt;a href="https://corebaseit.com/diagrams/monolithic13.png" target="_blank" rel="noopener">
&lt;img src="https://corebaseit.com/diagrams/monolithic13.png" alt="From monolithic to microservices 13" style="max-width: 720px; width: 100%; height: auto;" />
&lt;/a>
&lt;/p>
&lt;p>We have distributed the applications while preserving much of the original coupling.&lt;/p>
&lt;p>This is sometimes a valid &lt;strong>transitional state&lt;/strong>.&lt;/p>
&lt;p>It is a poor place to stop accidentally.&lt;/p>
&lt;p>A stronger destination is explicit ownership:&lt;/p>
&lt;p style="text-align: center;">
&lt;a href="https://corebaseit.com/diagrams/monolithic14.png" target="_blank" rel="noopener">
&lt;img src="https://corebaseit.com/diagrams/monolithic14.png" alt="From monolithic to microservices 14" style="max-width: 720px; width: 100%; height: auto;" />
&lt;/a>
&lt;/p>
&lt;p>Now another problem appears.&lt;/p>
&lt;p>A database transaction can no longer quietly coordinate everything.&lt;/p>
&lt;p>Distributed boundaries force previously hidden architectural questions into the open:&lt;/p>
&lt;ul>
&lt;li>What is the source of truth?&lt;/li>
&lt;li>Which service owns the state transition?&lt;/li>
&lt;li>What happens when a downstream call fails?&lt;/li>
&lt;li>Do we need eventual consistency?&lt;/li>
&lt;li>What is retried?&lt;/li>
&lt;li>What must be idempotent?&lt;/li>
&lt;li>What happens if an event is delivered twice?&lt;/li>
&lt;li>How do we reconcile inconsistent states?&lt;/li>
&lt;/ul>
&lt;p>Microservices do not eliminate complexity.&lt;/p>
&lt;p>They &lt;strong>move complexity across boundaries&lt;/strong>.&lt;/p>
&lt;h2 id="project-management-has-to-follow-the-architecture">Project management has to follow the architecture
&lt;/h2>&lt;p>Traditional project plans often describe migration in technical tasks:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>Create repository
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Create service
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Create database
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Implement endpoints
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Deploy service
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>All of those tasks can be completed while the migration itself remains nowhere near finished.&lt;/p>
&lt;p>A more meaningful plan tracks &lt;strong>capability ownership&lt;/strong>.&lt;/p>
&lt;p>For example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>Refund Extraction
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[✓] Boundary agreed
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[✓] ADRs accepted
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[✓] Service operational
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[✓] Observability available
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[✓] Data ownership established
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[✓] Shadow validation passed
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[✓] 5% production traffic
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[✓] 25% production traffic
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[ ] 100% production traffic
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[ ] Old refund path disabled
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[ ] Old database access removed
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[ ] Dead code removed
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This changes what &amp;ldquo;done&amp;rdquo; means.&lt;/p>
&lt;p>The service existing is not the milestone.&lt;/p>
&lt;p>The responsibility having moved is.&lt;/p>
&lt;h2 id="every-migration-step-needs-an-exit-condition">Every migration step needs an exit condition
&lt;/h2>&lt;p>One of the most useful disciplines in architecture programmes is defining what allows the team to move to the next phase.&lt;/p>
&lt;p style="text-align: center;">
&lt;a href="https://corebaseit.com/diagrams/monolithic15.png" target="_blank" rel="noopener">
&lt;img src="https://corebaseit.com/diagrams/monolithic15.png" alt="From monolithic to microservices 15" style="max-width: 720px; width: 100%; height: auto;" />
&lt;/a>
&lt;/p>
&lt;p>Without exit criteria, migrations tend to move according to calendar pressure:&lt;/p>
&lt;blockquote>
&lt;p>We planned to switch on Thursday.&lt;/p>&lt;/blockquote>
&lt;p>With exit criteria, the decision becomes evidence-based:&lt;/p>
&lt;blockquote>
&lt;p>Error rate, latency and reconciliation are inside the agreed thresholds, so we can increase traffic.&lt;/p>&lt;/blockquote>
&lt;p>That is a very different engineering culture.&lt;/p>
&lt;h2 id="observability-is-part-of-the-migration-architecture">Observability is part of the migration architecture
&lt;/h2>&lt;p>A migration without observability is extremely difficult to control.&lt;/p>
&lt;p>Before moving production traffic, the new boundary should expose enough information to answer:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>Is it working?
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Is it slower?
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Is it failing differently?
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Are retries increasing?
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Are duplicate requests appearing?
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Where is time being spent?
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Can we correlate the request across systems?
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>That means metrics, logs, and distributed traces are not something to &amp;ldquo;add later.&amp;rdquo;&lt;/p>
&lt;p>They are part of the migration mechanism.&lt;/p>
&lt;p>During the transition, a trace may cross both worlds:&lt;/p>
&lt;p style="text-align: center;">
&lt;a href="https://corebaseit.com/diagrams/monolithic16.png" target="_blank" rel="noopener">
&lt;img src="https://corebaseit.com/diagrams/monolithic16.png" alt="From monolithic to microservices 16" style="max-width: 720px; width: 100%; height: auto;" />
&lt;/a>
&lt;/p>
&lt;p>Without correlation across that boundary, operational complexity increases precisely when the architecture is already at its most complicated.&lt;/p>
&lt;h2 id="decommissioning-is-part-of-the-project">Decommissioning is part of the project
&lt;/h2>&lt;p>Migration projects have a dangerous moment:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>New service works.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Production uses it.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Everyone celebrates.
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>But the old implementation remains.&lt;/p>
&lt;p>Six months later:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>Refund Service
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> +
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Old Refund Module
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> +
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Old Tables
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> +
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Old Jobs
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> +
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Compatibility Code
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> +
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Temporary Routing
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The organisation now owns more architecture than before the migration.&lt;/p>
&lt;p>Decommissioning therefore belongs in the original plan.&lt;/p>
&lt;p style="text-align: center;">
&lt;a href="https://corebaseit.com/diagrams/monolithic17.png" target="_blank" rel="noopener">
&lt;img src="https://corebaseit.com/diagrams/monolithic17.png" alt="From monolithic to microservices 17" style="max-width: 720px; width: 100%; height: auto;" />
&lt;/a>
&lt;/p>
&lt;p>Deleting the old architecture is not cleanup.&lt;/p>
&lt;p>It is the final migration phase.&lt;/p>
&lt;h2 id="architecture-and-project-management-meet-in-the-middle">Architecture and project management meet in the middle
&lt;/h2>&lt;p>A system architect can draw an excellent target:&lt;/p>
&lt;p style="text-align: center;">
&lt;a href="https://corebaseit.com/diagrams/monolithic18.png" target="_blank" rel="noopener">
&lt;img src="https://corebaseit.com/diagrams/monolithic18.png" alt="From monolithic to microservices 18" style="max-width: 720px; width: 100%; height: auto;" />
&lt;/a>
&lt;/p>
&lt;p>A project manager can build an excellent roadmap:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>Q1 → Q2 → Q3 → Q4
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Neither is sufficient alone.&lt;/p>
&lt;p>The useful artifact connects them:&lt;/p>
&lt;p style="text-align: center;">
&lt;a href="https://corebaseit.com/diagrams/monolithic19.png" target="_blank" rel="noopener">
&lt;img src="https://corebaseit.com/diagrams/monolithic19.png" alt="From monolithic to microservices 19" style="max-width: 720px; width: 100%; height: auto;" />
&lt;/a>
&lt;/p>
&lt;p>This is where architecture stops being a picture of the future and becomes an executable strategy.&lt;/p>
&lt;h2 id="the-migration-itself-is-architecture">The migration itself is architecture
&lt;/h2>&lt;p>There are really three architectures involved:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>CURRENT STATE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> │
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ▼
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>TRANSITION ARCHITECTURE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> │
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ▼
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>TARGET STATE
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Teams naturally spend most of their design effort on the first and third.&lt;/p>
&lt;p>The middle deserves just as much attention.&lt;/p>
&lt;p>During migration, the organisation may temporarily operate duplicate paths, compatibility APIs, routing rules, event bridges, shared databases, shadow traffic, feature flags, and synchronization mechanisms.&lt;/p>
&lt;p>Those components may never appear in the final diagram.&lt;/p>
&lt;p>They still need architecture decisions, ownership, observability, security, testing, and explicit retirement plans.&lt;/p>
&lt;p>That is why a large architectural migration is not simply a refactoring exercise.&lt;/p>
&lt;p>It is the controlled evolution of a running system.&lt;/p>
&lt;h2 id="a-useful-mental-model">A useful mental model
&lt;/h2>&lt;p>The entire approach can be reduced to:&lt;/p>
&lt;p style="text-align: center;">
&lt;a href="https://corebaseit.com/diagrams/monolithic20.png" target="_blank" rel="noopener">
&lt;img src="https://corebaseit.com/diagrams/monolithic20.png" alt="From monolithic to microservices 20" style="max-width: 720px; width: 100%; height: auto;" />
&lt;/a>
&lt;/p>
&lt;p>Or even more compactly:&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>Architecture defines the destination. Migration architecture defines the safe path. Project management makes that path executable.&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>A monolith does not become a healthy microservice architecture because enough services were created.&lt;/p>
&lt;p>The migration succeeds when responsibilities, data ownership, traffic, operational ownership, and failure handling have moved deliberately — and the old architecture can finally be deleted.&lt;/p>
&lt;p>That is a much more meaningful definition of done.&lt;/p>
&lt;h2 id="references">References
&lt;/h2>&lt;ol>
&lt;li>Fowler, M. — &lt;em>Strangler Fig Application&lt;/em>. MartinFowler.com.&lt;/li>
&lt;li>Newman, S. — &lt;em>Monolith to Microservices: Evolutionary Patterns to Transform Your Monolith&lt;/em>. O&amp;rsquo;Reilly Media.&lt;/li>
&lt;li>Newman, S. — &lt;em>Building Microservices&lt;/em>, 2nd Edition. O&amp;rsquo;Reilly Media.&lt;/li>
&lt;li>Ford, N., Richards, M., Sadalage, P. &amp;amp; Dehghani, Z. — &lt;em>Software Architecture: The Hard Parts&lt;/em>. O&amp;rsquo;Reilly Media.&lt;/li>
&lt;li>Richards, M. &amp;amp; Ford, N. — &lt;em>Fundamentals of Software Architecture: An Engineering Approach&lt;/em>. O&amp;rsquo;Reilly Media.&lt;/li>
&lt;li>Nygard, M. — &amp;ldquo;Documenting Architecture Decisions.&amp;rdquo;&lt;/li>
&lt;li>Fowler, M. — &lt;em>Feature Toggles (aka Feature Flags)&lt;/em>.&lt;/li>
&lt;li>Corebaseit — &lt;a class="link" href="https://corebaseit.com/corebaseit_posts/spike-first-adr-second/" >Spike First, ADR Second: Evidence and Rationale in System Design&lt;/a>.&lt;/li>
&lt;/ol></description></item></channel></rss>