Replace or document: deciding on a legacy system integration
Not every ageing interface needs rebuilding. This is a structured way to decide whether an inherited integration should be replaced, documented and left running, or simply monitored until a genuine trigger arrives.
The real cost of carrying a legacy system integration
Almost every organisation we work with has at least one legacy system integration that nobody volunteers to discuss. It was written by a contractor who has moved on, or by an internal developer who left three years ago. It runs on a schedule, it mostly works, and the only person who understands it is the finance manager who knows that if the 06:00 file has not appeared by 08:30, someone needs to re-run it. The question that lands on the table is usually framed as technical — should we rebuild this? In practice it is a commercial question about the cost of carrying the thing for another two or three years, measured against the cost and disruption of replacing it.
Cost of carry is rarely a single line in a budget, which is why it tends to be underestimated. It is distributed across several people's weeks in small increments: the twenty minutes someone spends each Monday checking that stock figures agree, the half day of investigation when a transfer silently skips a batch, the three-week delay on an unrelated project because nobody is willing to change a shared table that the old interface reads from. Before deciding anything, it is worth spending two or three weeks instrumenting the existing interface so that these costs stop being anecdotal.
A reasonable measurement exercise does not require re-engineering. Add a log line at the start and end of each run, record the record count and the duration, and ask the people who babysit it to keep a simple tally of interventions. One client running a nightly export between a Microsoft Dynamics NAV installation and Peoplevox discovered that what they believed was an occasional issue was in fact a manual correction eleven times in a month, each taking between ten and ninety minutes. That number changed the conversation entirely, and it changed it in a direction that no architectural argument had managed.
The components worth quantifying before any decision is taken are these.
- Intervention time — Hours per month spent re-running, correcting or reconciling, including the hours spent by people outside IT. Price it at loaded cost, not salary.
- Change tax — The additional estimate attached to any project that has to touch the same data. If every adjacent piece of work carries a fortnight of defensive testing, that is a recurring cost of the legacy interface.
- Key person exposure — The number of people who could diagnose a failure at month end without external help. If the answer is one, or zero, that is a risk with a monetary value attached to it.
- Error cost — What an undetected failure actually costs. A missed stock update is a few oversells. A missed revenue posting is a restated management account.
Six signals that justify replacement
Replacement is justified when something has changed, or is about to change, that the existing design cannot absorb. Age on its own is not a signal. An interface written in 2014 that moves the same twelve fields it has always moved, on a platform that is still supported, is not a problem simply because it is old. The signals that matter are those that convert a stable arrangement into an unstable one.
The first is an externally imposed deadline. A platform vendor retiring an API version, a bank changing authentication requirements, or an operating system reaching end of support will force the issue on a date you do not control. The second is a runtime that can no longer be patched. If the integration runs on a server that cannot receive security updates, the conversation has moved from engineering to risk management and should be escalated accordingly.
The third is volume. Many older interfaces were designed around full-table extracts because the tables were small. When a nightly job that once took four minutes now takes two hours and overlaps the next day's trading, the design has been outgrown rather than merely aged. The fourth is a queue of blocked change requests. If the business has wanted three specific changes for the last eighteen months and none has been attempted, the interface is already imposing a cost that nobody has written down.
The fifth is absence of any safe way to test. If there is no non-production environment and no way to run a change without affecting live data, the effective cost of every future modification is enormous, and will stay enormous. The sixth is a compliance or audit requirement that the existing design cannot evidence — most commonly an inability to show who changed what, when, and on what authority.
- Fixed external deadline — An API retirement, certificate change or authentication deprecation with a published date.
- Unpatchable runtime — A server, language version or library that can no longer receive security fixes.
- Outgrown design — Run times, memory use or lock contention that have become operationally significant.
- Blocked change backlog — Business requests that have been refused or deferred because the interface is too risky to touch.
- No testable path — No environment in which a change can be proven before it affects live records.
- Unevidenced processing — No reliable record of what was sent, received, rejected or amended.
When documenting the legacy system integration is enough
The opposite case is more common than the industry generally admits. A great many inherited interfaces are stable, narrow in scope, and economically rational to leave alone. The conditions are specific: the data contract has not changed in years and is not expected to; the volume is well within the design's capacity; failures are visible rather than silent; and the blast radius of a failure is bounded and recoverable. Where those four conditions hold, replacement spends budget to achieve no measurable improvement in outcome, and introduces the risk that always accompanies new code touching financial records.
A worked example. A wholesaler receives orders into Shopify and posts summarised daily sales into Sage 200 through a scheduled job written several years ago. The mapping covers eight nominal codes and two VAT rates. It has failed twice in three years, both times visibly, both times recoverable by re-running a single day. The finance team reconciles monthly and has never found a discrepancy that originated in the interface. Replacing that would cost real money and deliver nothing beyond a tidier codebase. What it genuinely lacks is documentation: if the one person who knows the nominal mapping were unavailable during a year end, the organisation would be in difficulty.
There is a middle position that is frequently the right one. Leave the interface running, document it properly, and add observability around it — alerting on non-completion, a daily record count published somewhere a human will see it, and a recorded reconciliation check. This converts an opaque dependency into a monitored one for a fraction of the cost of replacement, and it buys time to replace it deliberately rather than under pressure.
What adequate documentation actually contains
Documentation that only describes what the code does is of limited use, because the code already describes that. Useful documentation captures the things that are not recoverable from reading source: the business intent behind each mapping decision, the credentials and where they live, the failure modes that have actually occurred, and the procedure for recovery. It should be written so that a competent person who has never seen the system can restore service at 07:00 on a Monday without telephoning anyone.
We treat a documentation engagement as a defined deliverable with an agreed scope and a fixed estimate, in the same way as a build. It is read-only work against the live system, usually combined with a short observation window, and the output is a document that is handed over and owned by the client. The sections below represent the minimum we would consider complete.
One section deserves particular emphasis: the decommission trigger. Write down, explicitly, the conditions under which this interface must be replaced — the API version it depends on, the volume ceiling, the operating system support date. Documentation that includes its own expiry conditions turns a deferred decision into a scheduled one.
- Data contract — Every field moved, its source, its destination, the transformation applied, and the business reason for that transformation. Nominal codes and tax treatments stated in full.
- Trigger and schedule — What causes the interface to run, where the schedule is configured, and what happens if a run is missed or overlaps.
- Credential inventory — Which accounts, keys and certificates are used, where they are stored, who owns them, and when they expire.
- Known failure modes — Each failure that has occurred, how it presented, and what was done. This is the section that takes the longest and saves the most.
- Recovery procedure — Step-by-step re-run instructions, including how to establish what was already processed and how to avoid duplication.
- Dependency map — Everything upstream and downstream, including reports and spreadsheets that read the same tables.
- Decommission trigger — The specific, dated or measurable conditions under which replacement becomes mandatory.
Running the assessment and, if necessary, the replacement
The assessment itself should be time-boxed and should produce a written recommendation with numbers attached. Our discovery and data mapping stage for an inherited interface typically runs two to three weeks: reading the code where it exists, observing the running system, interviewing the people who intervene when it fails, and producing a field-level map of what actually moves. The output is a recommendation of replace, document, or document and monitor, each with an estimated cost and an explicit statement of what risk remains in each case. The client then decides with evidence rather than instinct.
Where replacement is the recommendation, it should almost never be a single cutover. The pattern that works is incremental: build the new path alongside the old, run both in parallel against live data with the new path writing to a staging area, and reconcile the outputs daily until the difference is zero or fully explained. Only then does the new path take over writing, and the old one is left dormant but intact for an agreed period. For a finance-facing interface, a full accounting period of parallel running is a reasonable minimum, because month end exercises paths that daily operation does not.
Scope discipline matters more here than on greenfield work. The temptation during replacement is to fix everything that was ever wrong with the original, which is how a six-week project becomes a six-month one. We agree the scope in writing before any code is written, and improvements beyond like-for-like behaviour are listed separately with their own estimates, to be taken or deferred as the client chooses. The acceptance criteria should be stated in business terms — the same orders produce the same postings, reconciled against a defined sample.
At handover, the client receives the code, the deployment instructions and the same documentation set described above, written for the replacement rather than the original. A replacement that leaves the organisation with no more understanding than it had before has solved a technical problem and recreated an organisational one. The purpose of the exercise, whichever route is chosen, is that the interface stops being something only one person understands.
Related platform guides
- Microsoft Dynamics NAV API integration
- Peoplevox API integration
- Shopify API integration
- Sage 200 API integration
Key points
- Measure the cost of carry before deciding: intervention hours, change tax, key person exposure and the cost of an undetected failure are usually larger than assumed and easy to record in two or three weeks.
- Age alone does not justify replacement. Replace when there is an external deadline, an unpatchable runtime, outgrown capacity, a blocked change backlog, no testable path, or an audit requirement the design cannot meet.
- Where the interface is stable and bounded, documenting it with a recovery runbook and adding monitoring converts an opaque dependency into a managed one at a fraction of the cost of rebuilding.
Planning an integration?
Send us the two systems and the record types involved. We will come back with an outline scope and the approach we would recommend, within one working day.