The rewrite that fails is almost always the one that needed everyone to stop for a while. Product waits, the branch drifts, the business changes underneath it, and nine months later someone quietly proposes shelving the whole thing.
There is a version of this that works. It is slower to start and considerably less satisfying to plan, and it ships the entire time.
Instrument before you draw boxes
Almost every team we meet has already drawn the target architecture. It usually mirrors the org chart, which is a reasonable heuristic and a poor design input.
Spend four to six weeks tracing actual call graphs and data access. On one engagement, two of the four planned services shared a hot table so tightly that splitting them would have added a network hop to the system's busiest path. That finding saved a quarter.
Extract in dependency order, smallest first
Your first extraction should be almost embarrassingly safe. Its purpose is to build the tooling — the deployment template, the contract test harness, the observability wiring — that every later extraction reuses.
Teams that start with the hardest service to prove they can do it usually prove something else instead.

The migration pattern that never leaps
- Write an interface in front of the code you intend to move, in place
- Stand up the new service behind that interface, dark
- Dual-write and compare, logging every divergence
- Move reads over behind a flag, a percentage at a time
- Only when divergence has been zero for a sustained window, delete the old path
Keep the seam visible
During migration you have two implementations of the same behavior, and the temptation is to hide that. Don't. A dashboard showing divergence count per endpoint, visible to the whole team, converts an act of faith into an observable process.
It also makes the deletion step a celebration rather than a leap. You delete when the graph has been flat at zero for two weeks, not when someone feels ready.
