Split a monolith into microservices without breaking its contracts
Usually an architect, with the leads of the teams taking a slice each
Slice one app into several and say which contracts each new service carries, so a table or endpoint nobody picked up reads gone before a caller finds out.
The problem
A monolith serves hundreds of contracts: the endpoints its clients call, the events it publishes, the tables its reports read. When it is split, each new service takes the ones its team remembers. The ones nobody remembers stay served by the shrinking monolith until it is switched off, and then they are the outage.
The usual answer is a distributed monolith: the services exist, the boundaries are wherever the first cut landed, and every change still touches three repositories. Knowing which service owns which contract, and which contracts fell between them, is what makes the split a split.
How it goes
The same steps the product’s playbook walks. Each one shows the screen at that moment.
Map the monolith
Bind the monolith's repository and extract its contracts: every table, endpoint and event channel it serves, read from the code with the file and line each was found at. This is the list the split has to account for, and it is not written by hand.
Name the services that replace it
Declare the split on the root board: the monolith on one side, the new services on the other, each saying which part of the monolith it replaces. Every contract the monolith serves is compared by its key against what the new services serve.
Read what nobody picked up
A contract no new service serves reads gone. One served by a service that did not claim that part of the monolith reads moved, which is a boundary to decide on. A gone contract another system calls is flagged with that system's name, read from its own code.
Plan the slices as work items
Each gone contract becomes a work item on the service that should carry it, filed under the split's epic, with the contract attached. Order them on the grid in waves, one slice at a time, and hand off the first.
Watch each slice land
Each extraction on a new service serves its contracts, and their work items complete on their own. The headline counts the monolith's contracts down to every one kept by a service or accepted as retired with a reason.
- Proven by the code
End proofDone when every contract the monolith served is kept by the service that claimed it, or accepted as retired with a reason.
Works with
- Code
- The monolith's repository and each new service's, read by the code plugin inside Claude Code, Codex or Cursor; derived metadata is pushed, never your source.
- Contracts
- Tables, endpoints, event channels, pages and outbound calls, compared by their keys, each with the file and line it was read from.
- Services
- Two or more new apps on the after side, each saying which part of the monolith it replaces, so a contract kept by the wrong one reads moved.
- Work items
- The slices as work items in one epic, handed off in waves and claimed from a coding session; Jira and Slack when the team tracks work there.
- Plans
- Every step runs on the Free plan, including the confirmation by the code.
Where it stops
- The comparison reads the contracts the monolith serves outward. It does not slice its modules or classes for you, and it does not propose where the boundaries should go.
- Structure is not compared: the new services are meant to be shaped differently from the monolith, so only their contracts are lined up.
- A database every new service still reads is a kept table, not a seam. The table says the contract is served; it does not say the split is finished.
- A type spelled differently reads as a note on a kept row unless the rule is set to read shapes, and a field the extraction could not cite reads as not read.
- Two extractions can read the same code differently, such as an API-version parameter one records and the other does not. The row reads changed with what differs, and a person accepts it with a reason.
Why not a diagram, or a code browser
A diagram shows
The target services as someone drew them, with boxes for each and no list of the hundreds of contracts the monolith serves that have to end up in one of them.
A code browser shows
The monolith's code, or one new service's, never both against each other. Which endpoints fell between the services is a question for a spreadsheet.
ProvenMap shows
The monolith and every new service read from their own code into one table, each contract kept by the service that claimed it, moved to one that did not, gone, or new. The slices are work items on that table, and each closes when the service serves its contract.
Walk through it
- The docs walkthrough of this job is being written.
- In the product this job runs as the playbook Plan and track a migration. The board ticks each step when what it asked for exists.
The features behind it
Start with one system
Map a real system and see the architecture around it.
Open one repository and run the code plugin. No migration, no rollout, no diagramming.
No credit card · Analysis runs locally in your own session · Self-hosted available
See the four commands to your first board →
Or for writing on architecture that stays connected across systems.