Somewhere in your organization right now, a team is working on a “modernization initiative.” They’ve been working on it for a while. If you ask when it’ll be done, you’ll get a date that’s been moved at least twice, a qualified answer about “phases,” or, my personal favorite, a confident assertion that they’re “making great progress” followed by a refusal to define what “done” means.

You know this is happening because you approved the initiative. Or you inherited it. Either way, you’re responsible for it now, and somewhere in your gut you already know it’s not going the way it was supposed to.

Let’s talk about why.

The migration that never ends

Most platform modernization projects start the same way. Someone draws a diagram with two boxes: “Current State” on the left, “Target State” on the right, and a big arrow labeled “Migration” in the middle. Everyone agrees the current state is bad and the target state is good. The arrow gets a timeline. The timeline gets a budget. The budget gets approved.

Nobody spends enough time on the arrow.

The arrow is where your project will die. Not all at once. Slowly, incrementally, in a way that lets everyone involved maintain the polite fiction that things are on track. A dependency that wasn’t accounted for. A data migration that’s more complex than the estimate assumed. An integration that requires cooperation from a team that has their own priorities and doesn’t particularly care about yours. Each one is a reasonable delay. In aggregate, they’re a death sentence.

Here’s the part nobody says out loud: most platform modernization projects don’t fail because the target architecture was wrong. They fail because the organization treated migration as a technical problem when it’s actually an organizational one. The technology is the easy part. Getting six teams to coordinate a cutover sequence while maintaining production traffic and not regressing on features that real users depend on… that’s the hard part. And it’s the part that gets the least planning.

The strangler fig is not a strategy

Martin Fowler wrote about the strangler fig pattern years ago, and it’s become the default answer to “how do we modernize without a big bang rewrite.” The idea is elegant: incrementally replace components of the old system with new implementations, routing traffic gradually, until the old system is fully decomposed.

In practice, what usually happens is this: a team builds a new service that handles one slice of functionality. They set up routing to send some traffic to the new service and some to the old. Now they’re operating two systems. The new service needs data from the old system, so they build a sync layer. The sync layer has bugs, because sync layers always have bugs. Someone adds a feature to the old system while the new one is being built, so now the new system is already behind. The team that was supposed to decompose the next component got pulled onto a different priority.

Six months later, you don’t have a modernized platform. You have the old platform, a new service that handles 15% of traffic, a sync layer that nobody trusts, and a team that’s exhausted from operating both. Congratulations: you’ve made your architecture more complex and your operational burden heavier, and you’re calling it progress.

The strangler fig works. But it requires something most organizations aren’t willing to commit to: dedicated, sustained investment with a team that has the authority to make the rest of the organization cooperate. Without that, it’s not a migration strategy. It’s a way to build a second system that you also can’t get rid of.

The rewrite fantasy

On the other end of the spectrum are the teams that decide to just start over. New stack, new architecture, greenfield. They’re tired of the constraints of the old system and they want to do it right this time.

This is the engineering equivalent of leaving your spouse because you think the next relationship will be different. The new system won’t have the old system’s problems. It’ll have new problems. And in about eighteen months, someone will be standing in front of a whiteboard explaining why this system also needs to be modernized.

The rewrite fantasy is seductive because it lets you pretend that the hard problems are technical. They’re not. The hard problems are the business rules embedded in code that nobody fully understands, the edge cases that were discovered in production and patched without documentation, and the operational knowledge that lives in the heads of three people who’ve been running the old system for seven years. You’re not rewriting code. You’re trying to reverse-engineer institutional knowledge into a new codebase. Good luck doing that on a timeline.

The teams that actually succeed at rewrites (and some do) succeed because they’re ruthlessly honest about what they don’t know. They budget more time for discovery than for building. They run both systems in parallel for longer than anyone is comfortable with. And they accept that the new system will launch with fewer features than the old one, because getting to production matters more than achieving parity.

What actually works

The effective platform modernization work we’ve been part of has a few things in common, and none of them are sexy:

Ruthless scope control. Not “what does the target state look like?” but “what is the smallest change we can make that meaningfully reduces risk or unlocks capability?” Every modernization project that succeeds is actually a series of small projects, each delivering value on its own. Every one that fails is a single large project that delivers value only at the end.

Honest dependency mapping. Not the architecture diagram you wish you had, but the actual dependency graph, including the ones that are embarrassing. The batch job that runs on Steve’s machine every Tuesday. The stored procedure that nobody wrote but everyone depends on. The CSV export that feeds a workflow in another department. You can’t migrate what you don’t acknowledge exists.

Organizational air cover. Someone with enough authority to say “this team’s priority is the migration, full stop” and make it stick for six months. Not “the migration is one of our priorities.” The migration. Full stop. Every modernization project that stalls does so because the team got loaded with competing priorities and the migration became the thing they worked on when they had time, which was never.

A definition of done that isn’t “feature parity.” Feature parity is a trap. It means you’re committing to rebuilding every decision the old system ever made, including the bad ones. Define done as “the old system is turned off” and work backward from there. Some features won’t make the cut. That’s not a failure. That’s editing.

The question to ask yourself

If you’re in the middle of a modernization project right now, here’s the question: can you point to a specific thing that’s different today than it was six months ago? Not “we designed” or “we planned” or “we’re building.” Something that’s running in production, serving real traffic, on the new platform.

If you can’t, you don’t have a modernization project. You have a planning exercise that’s burning runway.

The difference between the two is someone willing to make it real. That’s the work we do.


Steadfast Digital helps engineering teams finish the modernization projects that stalled. If your migration timeline has been revised more than twice, we should talk.