Name the constraint before choosing the method
A rewrite is justified by a constraint that cannot reasonably be removed within the current system. Examples might include a data model that prevents a necessary workflow or an architecture that cannot isolate critical failures. An old framework or frustrating code is a reason to investigate, not sufficient evidence for replacing a working product. Define the business capability that must change and how success will be judged.
Compare complete routes to the same outcome
A full rewrite offers a cleaner starting point, but the estimate must include undocumented rules, data migration, integrations, staff training and a period of parallel operation. Incremental improvement keeps users on a familiar product and tests assumptions sooner, while requiring clear boundaries between old and new components. Replacing a module without deciding who owns its data can create more complexity than it removes.
Compare the migration burden, not just new code
For both routes, list the customer outcome, the records moved, the integrations touched and the people who must change their work. Include rules that exist only in historical data or staff memory. In the pricing example, ask how discounts, expired contracts, manual overrides and previously issued quotations behave. A replacement that handles only new orders is not equivalent to a system that must also explain old ones. Use the same representative cases to compare both proposals, and mark unknowns explicitly rather than assuming a clean implementation will discover them later.
Choose a boundary with one accountable owner
An incremental replacement needs a clear point where old and new responsibilities meet. Decide which component calculates a price, which stores the accepted quotation and which can revise it. Run the new calculation against safe historical examples and investigate disagreements before making it authoritative. If a temporary comparison mode is used, prevent it from issuing invoices or other real effects twice. Name the operator who reviews differences and the condition for moving each contract type. A boundary is useful when it reduces uncertainty; a new interface that conceals several competing sources does not achieve that.
Define completion and retirement together
Before funding either route, describe how the old implementation will stop receiving new work and how its history remains available. Specify the final reconciliation, the required recovery evidence and the permissions removed after retirement. Keep a route back for the stages where reversal remains possible, with a policy for records created meanwhile. If a full rewrite is necessary, its milestones should still demonstrate usable slices and resolved migration risks. The final decision should connect replacement cost to the constraint it removes and make the ongoing cost of temporary coexistence visible.
A fictional order-management example
Suppose only the pricing engine blocks new contracts. One route replaces the whole order application; another places a tested pricing interface beside the existing workflow and migrates one contract type first. Compare both against the same outcomes: accurate quotations, explainable adjustments and reversible rollout. The smaller route loses its advantage if every quotation still requires unsafe writes across several systems.
Choose a first decision that can be revisited
Time-box a discovery exercise with Orvun Labs’s software-rescue service before committing the entire budget. Capture the findings that would change the recommendation. Avoid maintaining two full products indefinitely without a retirement condition.
- Which limitation has a measurable operational consequence?
- What can be isolated without duplicating the source of truth?
- Who validates the old rules against the replacement?
- What evidence permits retirement of the old component?