The platform has to change. The question is how: replace it with a clean-sheet build, or evolve the existing system toward the target.
This article is part of ZibiWorks, an ongoing fictional modernization case study. The ZibiWorks site is the canonical home of the series, with the full company context, starting architecture, and related installments. Explore the full series at ZibiWorks.
The infrastructure question is settled. ZibiWorks chose to move before
modernizing the application, but that decision left the monolith, the shared
database, and the tangled domains intact. With the migration path established,
attention turns to how the application itself should change.
The problem forcing the question
A specific business capability is under pressure: Order Fulfillment.
As ZibiWorks has grown, seasonal demand has grown with it, and Fulfillment
needs to scale more independently than it can today. Because Fulfillment is
embedded in the monolith, adding capacity for it means scaling far more of the
application than necessary, and problems or deployments in unrelated areas can
disrupt fulfillment processing. As order volume climbs, its availability and
resiliency matter more every quarter, and leadership wants this materially
improved before the next major peak season.
ZibiWorks is not modernizing for cleanliness. It has a business capability
that has to get better on a specific timeline, and that deadline is the single
most important criterion weighing on the decision.
Before comparing the two paths, one thing is worth settling: this is a decision
about how ZibiWorks travels, not where it is going. Whichever path it takes,
good domain analysis should land on substantially the same business
capabilities, bounded contexts, ownership, and data responsibilities. An
evolutionary path may surface new information along the way, so the final
implementation can differ in detail, but the migration mechanism should not
dictate the target decomposition. The destination is not what is in question
here.
Two credible options
Both are credible. Neither is foolish.
Option A — Rewrite
- Design and build the new platform alongside the existing system
- Migrate the business onto it
- Retire the old system
Option B — Evolve
- Create seams in the existing platform
- Move capabilities into new bounded contexts over time
- Retire legacy implementations as confidence grows
A clean rewrite is genuinely appealing: clean boundaries from day one, a modern
architecture without legacy compromises during construction, freedom to rethink
persistence and integration, and far less transitional scaffolding cluttering
the codebase. Building straight toward the desired end state is a real
advantage, and it deserves a serious evaluation rather than a reflexive "big
rewrites fail."
Evolution has its own strengths and its own real costs. The two differ on three
things that matter here: where the complexity lands, when the business sees
value, and how data moves.
Where the complexity lands
Neither approach avoids complexity; they place it differently in time. Both
involve substantial construction work. What differs is where the migration,
coexistence, validation, and cutover complexity falls.
| Dimension | Evolution | Rewrite |
|---|---|---|
| Complexity | Migration complexity distributed throughout the transition: temporary adapters, compatibility layers, and synchronization. | Cleaner construction path, but migration and cutover complexity concentrated near completion. |
| Delivery of value | Fulfillment can improve independently while the rest of the platform evolves. | Fulfillment improvements depend on enough of the replacement platform being ready. |
| Data migration | Incremental, domain by domain. Ownership and validation move in smaller steps. | Larger, coordinated migration and reconciliation near cutover. |
Evolution distributes migration complexity across the journey. A rewrite concentrates much of it near the destination.
Can a rewrite meet the deadline?
On construction alone, a rewrite might. The deciding question is not whether
ZibiWorks could build a replacement in time, but what it would take to put one
safely into production before the busiest period of the year.
A full-platform replacement couples the Fulfillment deadline to the readiness of
the entire new platform. Before peak season, ZibiWorks would have to validate
not just Fulfillment but every capability on it, resolve defects in capabilities
that are not driving the deadline, and complete data migration, reconciliation,
and a production cutover, then stabilize an entirely new platform right before
its highest-demand weeks.
Those pressures have nothing to do with Fulfillment. It could be
production-ready while defects in Customer Management or Billing hold up the
cutover, with QA and release capacity consumed by unrelated problems. Even a
rewrite delivered on time would send ZibiWorks into peak season on a platform
with little production history. The risk is not simply missing the date; it is
introducing broad operational uncertainty across the whole system at the exact
moment Fulfillment needs to be more reliable.
This is not an argument that rewrites fail. A narrowly scoped or phased
replacement could be viable under different constraints, and in that form it
starts to resemble evolution anyway. ZibiWorks is weighing a broad replacement
because its problems span the monolith, and at that scope the coordination and
stabilization risk against this deadline is what makes it hard to justify.
Could ZibiWorks buy more time?
The opposite move is to attempt nothing structural: scale out the existing
monolith, survive one more peak season, and defer modernization. It is a
legitimate option, and it turns on a distinction that is easy to blur, between
capacity and architectural resilience.
Horizontal scaling might handle the extra load, assuming Fulfillment's
bottleneck responds to additional compute. But more instances do not give
Fulfillment independent deployment or failure isolation, and the shared
constraints stay shared: database contention and synchronous dependencies can
remain, or even worsen as more instances press on the same backend. Scaling the
whole monolith to serve one capability raises cost too, though that is
secondary here.
Leadership asked for two things, scalability and resiliency. Additional
capacity may improve availability, but it does not eliminate the shared failure
risks Fulfillment faces within the monolith. Under lighter constraints, buying a
season of runway could be reasonable. For ZibiWorks it defers the problem rather
than reducing the risk it needs to retire before peak season.
Evaluating the options against the business needs
The choice becomes clearer when each approach is measured against what ZibiWorks
actually needs before peak season.
| Decision criterion | Full rewrite | Scale existing monolith | Evolve incrementally |
|---|---|---|---|
| Improve Fulfillment before peak season | Depends on full-platform readiness | Can improve capacity quickly | Can prioritize Fulfillment |
| Scale Fulfillment independently | Yes, after replacement | No | Yes, after extraction |
| Improve Fulfillment resilience | Can design for resilience, but benefits arrive with replacement | Can add redundancy; shared failure risks remain | Can improve resilience as Fulfillment is extracted |
| Isolate Fulfillment from unrelated failures | Yes, with appropriate boundaries | Existing application coupling remains | Yes, with appropriate boundaries |
| Minimize peak-season deployment risk | Coordinated cutover and stabilization | Smaller immediate change, existing coupling remains | Smaller incremental transitions |
| Continue broader modernization | Complete replacement | Deferred | Progressive modernization |
Leadership's requirements are explicit: improve Fulfillment's scalability and
resilience before peak season. Those are what the first rows measure. The rest,
deployment risk and the ability to keep modernizing, are supporting
architectural criteria rather than mandates, but they shape which option meets
the requirements safely. Read that way, no column strictly dominates. A rewrite
reaches the same target capabilities but gates them behind the whole
replacement; scaling adds capacity fastest but leaves the coupling and
resilience gap in place; evolution can act on Fulfillment first, provided the
extraction and its boundaries hold.
The decision
ZibiWorks chooses evolutionary modernization. It is the clearest path to
improving Fulfillment on its own timeline, without gating that improvement
behind a complete replacement. Scaling the monolith could improve capacity and,
through redundancy, availability, but it does not resolve the shared application
failure modes or give Fulfillment the independent failure isolation leadership's
resilience requirement implies. Evolution's gains are not free: they depend on
successfully extracting Fulfillment behind boundaries that hold. On ZibiWorks'
constraints that is the better bet than coupling Fulfillment's deadline to a
platform-wide cutover.
Under different constraints (no deadline, a smaller system, an appetite for one
coordinated cutover) the rewrite could be the better call. Here, the deadline
and the breadth of the system decide it.
What evolution requires
"Evolve the monolith" is a decision, not yet an architecture. Delivering it
means designing two architectures at once and keeping them distinct.
Target architecture
- The system ZibiWorks ultimately wants
- Domains, ownership, data responsibilities, integration
- Permanent
Migration architecture
- The temporary mechanisms that get there safely
- Adapters, shims, DI seams, sync paths, fallbacks, routing, bridges
- Designed to disappear
Keeping these separate is what stops the migration scaffolding from being
mistaken for the target. The migration architecture is real, designed work, even
though most of it is meant to be removed when the migration is done.
Reversibility, and its limit
One benefit of a designed migration architecture is that transitions can be made
reversible. The monolith depends on an interface representing a business
capability. Dependency injection first resolves that interface to the legacy
implementation; during migration it is swapped for an adapter that talks to a
newly extracted domain. From the monolith's point of view the contract is
unchanged even though the implementation boundary has moved, so routing can be
pointed back at the legacy implementation through configuration. A large
architectural change becomes a sequence of smaller, individually reversible
steps.
But routing rollback is not the same as business-state rollback. Flipping the
switch back is easy at the application boundary; whether it is safe depends on
what has happened to the underlying data. If the new domain has become
authoritative, how can the legacy implementation still be a viable fallback?
ℹ️ Data completeness and data authority are not the same thing
Authoritative writes can move to the extracted domain while the monolith keeps a complete enough representation of the data it needs, maintained from the new domain's events. The new domain owns the writes; the monolith's copy stays current enough for legacy workflows to keep running; the old implementation remains a plausible fallback. Call it dual presence, single authority: the data is present in both places, but only one side is the source of truth.
Completeness is not the same as authority, and it is not the same as safe rollback. Once authority has moved, reversing it also depends on state compatibility, business semantics, and the ability to reconcile whatever each side wrote in the meantime. Asynchronous synchronization keeps the fallback viable; it does not, by itself, guarantee a clean reversal.
Strangler Fig
With evolution chosen and the migration architecture understood, the Strangler
Fig pattern is the strategy that organizes the work. It gives the migration a
repeatable sequence: pick a capability, redirect its responsibility to a new
domain behind the existing contract, let old and new run side by side, move data
authority across once confidence builds, then retire the legacy implementation.
The cycle repeats, one capability at a time, until the monolith has been
strangled. Fulfillment is the natural first candidate, since it is the capability
under the most pressure.
The Scaffolding Fallacy
Most of that migration architecture is built to be thrown away, which invites a
tempting but wrong conclusion: that if something is going to be removed later,
the effort spent building it must be waste. Construction scaffolding is temporary
and is no part of the finished building, yet no one calls it wasted. Its value is
letting the building go up safely. Migration architecture is the same. It can
have no place in the target and still be worth a great deal during the
transition.
The guardrail is that "temporary" is not a license for uncontrolled complexity.
Scaffolding that earns its place has a purpose, a transition it enables, an
owner, and a known removal condition.
Temporary by design is very different from accidentally permanent. The problem
is not throwaway code; it is throwaway code that nobody ever throws away.
Consequences
The decision is a trade made with its costs in view.
What ZibiWorks gains
- Fulfillment addressed first, ahead of peak season
- Business value arriving earlier, not at the end
- Smaller, independently validated transitions
- A smaller blast radius per change, with more chances to roll back
- Data migration spread across the program
- No single platform-wide cutover
What ZibiWorks accepts
- Temporary architecture and some disposable code
- Coexistence between old and new
- Eventual-consistency and synchronization concerns
- Added operational complexity during migration
- The ongoing job of actively retiring scaffolding
The right column is the price of the left one.
ZibiWorks has now decided to modernize, chosen evolution, and settled on
Strangler Fig as the approach. But a strategy is not a cut line. If a capability,
starting with Fulfillment, is going to move out of the monolith one piece at a
time, the next thing to understand is where the system can safely come apart.
ZibiWorks is fictional. The ideas and opinions expressed throughout the series are my own and do not represent the views, positions, or practices of my employer.
Top comments (0)