New: CentriCall AI voice agents that answer, qualify, and book around the clock
EnterpriseCloud and DevOps7 min read

How a 900-person distributor modernized a 17-year-old order system without a single big-bang cutover

A pricing change took six weeks — not because the change was hard, but because the regression surface was unknown. A full rewrite had been quoted at eighteen months and cancelled once already.

At a glance

Client
a North American industrial parts distributor, roughly 900 staff across eleven branches, in the United States and Canada
Industry
Enterprise
Engagement
Cloud and DevOpstime and materials
Duration
16 months, then an ongoing support retainer
Team
5 engineers, 1 architect, 1 SRE, embedded alongside two client developers

What changed

25822days

to make a pricing change, down from roughly six weeks

03600

planned downtime windows across the whole migration — which is what “no big bang” means in practice

3693326011

of about 40 shadow spreadsheets and Access databases retired, because the system finally did what they compensated for

Figures are as reported by the client over the period named in the body below, and were not independently audited by us.

The short version
  • The estate was ranked by risk and value before anything moved. Not every application deserves a rebuild, and two of them deserved deletion.
  • Pricing was taken out first — highest change frequency, smallest blast radius — so the approach was proven on something that mattered and could be reversed.
  • The database stayed where it was until the last seam. In a system this age the database is usually the hard part, not the application.
  • Every seam shipped behind a flag and could return to the monolith the same afternoon. None of them needed to, and the option is what made the sequence acceptable to the branches.

The problem

Order entry and pricing ran on a .NET Framework application first shipped in 2008, integrated with a Java warehouse system nobody had upgraded since. Two of the original developers were still on staff. Neither wanted to touch it, and both were right not to.

A pricing change took six weeks. The change itself took a day. The other five weeks were working out what else the change would break, because there were no tests, and then negotiating a release window with eleven branches who had each been burned before.

  • A full rewrite had been quoted at eighteen months and cancelled, at some cost, before we were involved. The organisation had already paid for one failed answer.
  • More than forty Access databases and spreadsheets had grown up around the gaps. Every one of them was now load-bearing, and none of them was backed up.
  • Nobody could describe the regression surface. Not because the documentation was bad, but because there was none, and the people who held it in their heads had left over seventeen years.

What made it hard

What we did

1

Ranked the estate before moving any of it

Nine candidate seams, scored on change frequency, business risk, and coupling. Two applications came out of that exercise marked for deletion rather than migration — they had users, but the users had workarounds they preferred. Deleting them was the cheapest modernization in the programme.

2

Put a routing façade in front of the monolith

One entry point, able to send a request to the old code or the new, per route, per flag. Everything afterwards depended on this. Without it, each seam is a cutover; with it, each seam is a toggle.

3

Took pricing out first

Highest change frequency, smallest blast radius. The point of going first is not the value of the seam — it is that the approach gets proven on something that matters enough for people to pay attention and is contained enough to reverse. A first seam nobody cares about proves nothing.

4

Built the Azure landing zone inside their own tenant

In their subscription, inside the change control they are already audited against, using the identity provider their staff already had. A landing zone that sits outside the organisation's existing controls creates a second compliance regime, and the second one always turns out to be somebody's job later.

5

Left the database until the last seam

The schema was shared by everything and understood by nobody in full. Moving it early would have put the hardest, least reversible change first, at the point when the team knew least. It moved once eight of nine seams were reading through code we had written and tested.

6

Made tests, runbooks, and decision records deliverables per seam

Not a closing task. Each seam shipped with the characterisation tests that pinned the old behaviour, the runbook for its failure modes, and a written record of what was decided and what was rejected. That record is what makes seam six cheaper than seam two.

Why we did not rewrite it

Because the specification for the rewrite did not exist. Seventeen years of behaviour, including the parts that are wrong and the parts that are wrong on purpose for a customer who complained in 2016, live only in the running system. A rewrite has to reproduce all of it and cannot enumerate it, which is why the pattern fails often enough to have a literature.

The seam-by-seam approach does not need the specification. It needs the old system to keep running while each piece is characterised, replaced, and verified against it — which is slower per seam and dramatically faster to a first result. Modernising a legacy system without a big-bang rewrite sets out the full argument.

What changed

Week92599

first seam live; six of nine live by month 14

25822days

to make a pricing change, from roughly six weeks

03600

planned downtime windows across the migration

SeamLiveWhy it was sequenced there
PricingWeek 9Highest change frequency, smallest blast radius — proves the approach
Product catalogueMonth 5Read-mostly, feeds everything else, low write risk
Order entryMonth 8The reason for the programme; needed the first two to be stable
Branch stock enquiryMonth 10Retired nine of the shadow spreadsheets on its own
Warehouse integration (Java)Month 12Third-party contract, needed the vendor in the room
Customer accountsMonth 14Highest coupling; deliberately late
Reporting, returns, databaseIn progressDatabase last, by design
Two of the original nine candidates were deleted rather than migrated, which is why the list runs to seven.

The pricing lead time is the figure the business cares about, and the mechanism is not that the new code is faster to change. It is that the new code has characterisation tests, so the five weeks of working out what else might break became a test run.

Thirty-one of the forty-odd shadow spreadsheets have been retired. That number matters more than it looks: each one was an undocumented, unbacked-up dependency of a 900-person business, and they existed because the system did not do something. They went away when it did.

The constraints we worked under

What this engagement did not include
  • Three seams are still in the monolith at the time of writing, including reporting and the database itself. The programme is not finished and we would not describe it as finished.
  • The Java warehouse system was integrated with, not replaced. It is under a third-party contract and replacing it was never in scope.
  • Nine shadow spreadsheets survive. Some encode branch-level pricing discretion that the business has not yet decided whether it wants to formalise, which is a policy question rather than a technical one.
  • We cannot show a cost saving. The programme cost more than doing nothing, and the return is in change lead time and risk rather than in a line on the infrastructure bill.
  • One thing we would do differently: we built the routing façade in week three and should have built it in week one. The estate ranking could have run alongside it rather than before it.

What they own now

  • The repository, in their own Azure DevOps organisation, with two of their developers as maintainers from month one rather than at handover.
  • The Azure landing zone, in their tenant, under the change control they were already audited against.
  • Characterisation tests pinning the behaviour of every seam that has moved, including the behaviour that is wrong on purpose.
  • An architecture decision record per seam, written for someone who was not in the room, covering what was rejected as well as what was chosen.
  • The routing façade and its flags, which is what makes the remaining three seams a continuation rather than a new project.

When this would not have worked

Seam-by-seam modernization is the right answer more often than a rewrite, but not always, and the exceptions are worth naming.

  • If the old system cannot be kept running — an unsupported runtime with a known exploit, or hardware nobody sells — you do not have the luxury of a sequence, and the conversation is about containment first.
  • If the business is about to change fundamentally, characterising seventeen years of behaviour preserves rules that are about to be thrown away. Modernisation is not a virtue in itself.
  • If nobody internal will be on the programme, the decision record has no reader and the handover has no recipient. Two client developers embedded throughout is why the remaining seams are theirs to finish.
  • If the estate is small enough to hold in one head, the façade and the ranking are overhead. This shape earns its cost somewhere above a handful of applications.

If this sounds like your situation

The capability is cloud solutions for enterprise and the embedded model is IT staffing for enterprise. The engagement shape is cloud and DevOps, continuing as maintenance and support. If you are weighing this against a rewrite or a package, build versus buy and what drives cloud migration cost are the two to read.

If the old system has not shrunk, you are not modernizing it. You are building a second one beside it.
The first time a seam went live nobody in the branches noticed. That was the point, and it was also the thing I did not believe would happen.
VP Information Technology, a North American industrial parts distributor

Recognise any of this?

Tell us what is not working. You will get a scoped estimate and an architecture you own, not a capability deck.

Common questions

For an estate this size, the first seam was live in week nine and six of nine were live by month 14, with three still to go. That is the honest shape: a first result inside a quarter and a programme measured in years. Anyone quoting a fixed end date for a system whose behaviour is not documented is pricing an assumption, which is exactly what the cancelled eighteen-month rewrite did.
A single entry point in front of the old application that can send each request either to the old code or to its replacement, controlled by a flag. It is what turns every subsequent seam from a cutover into a toggle, and it is why this programme had no planned downtime windows. Build it before you move anything; we built it in week three and should have built it in week one.
Because in a system this age the schema is shared by everything, understood in full by nobody, and the least reversible thing you can touch. Moving it early puts the hardest change at the point when the team knows least about the system. It moves once most of the code reading it is code you wrote and tested.
They retire on their own as the system starts doing what they compensated for — thirty-one of about forty here, with the branch stock enquiry seam accounting for nine by itself. The survivors are worth examining rather than deleting: several encode a discretion the business genuinely wants, which is a policy decision to make deliberately rather than a gap to close by default.
We strongly prefer it, and here two client developers were maintainers from month one. The decision records and characterisation tests are written for someone who was not in the room, but a document has to have a reader. It is also why the three remaining seams are something their team can finish without us.