The Overgrown Trail

The batch job ran every night at 11 PM. It processed inter-hospital billing reconciliation: matching charges, validating payments, resolving discrepancies across facilities. It took an hour. And it was getting slower.

Not dramatically. A few minutes longer each month. Fifty-eight minutes became sixty-two. Then sixty-five. Then seventy. Nobody raised an alarm because there was no alarm to raise. No threshold was crossed. No incident was filed. The business adapted. Schedules shifted. Downstream processes started a little later. And the job kept running, a little slower each time.

“Nobody touched it.”

Four words that carry the thesis. Not “nobody maintained it” in the usual sense. The code hadn’t been modified in years. The engineers who built it were gone. The ones who inherited it had learned not to ask questions. They watched it run, watched it finish, and went back to work on things they understood.

The System Nobody Wanted to Touch

The system handled healthcare billing reconciliation: the process of matching charges between hospitals, validating payments, and flagging discrepancies. Get it wrong and you’re looking at real financial exposure. Get it wrong in healthcare and you’re also looking at compliance problems that don’t resolve themselves.

The batch job sat at the center of this. Every night it ingested the day’s transactions, ran them through validation and matching logic, and produced reconciled output. It was critical infrastructure in the way that only invisible infrastructure can be: nobody thought about it until someone imagined it failing.

That imagination was enough to create a culture of avoidance. No tests. No documentation. No one who understood the internals. The engineers who built it had moved on years ago. The ones left behind had a single operating principle: don’t touch that.

This wasn’t laziness. It was rational self-preservation. If you change code that has no tests, in a domain you don’t fully understand, touching data with compliance implications, and something breaks, that’s your name on the incident. The math was simple: risk of change vastly exceeded the perceived cost of leaving it alone.

And each month of success reinforced the calculation. The system ran for another thirty days without failing. It must be fine. The evidence that it was deteriorating (the slowly growing processing time) was easy to ignore precisely because it never crossed a threshold. There was no alert. No error. Just a system that took sixty-two minutes instead of fifty-eight, easy to dismiss as noise.

The trail into this system had been overgrown for years.

What “Neglect” Really Means

Neglect gets framed as a moral failing. Someone should have maintained this. But in practice, neglect is almost always a series of reasonable decisions that compound.

Year one: the team that built it ships the system. It works. They move on to the next project.

Year two: a new team inherits it. They don’t fully understand it, but it runs. They have their own priorities. They leave it alone.

Year three: someone notices the processing time has increased, but it’s still within acceptable bounds. No action is taken. There’s no spec to compare against. “It takes about an hour” becomes the baseline.

Year four: the understanding gap has widened to a chasm. The engineers who built it are at other companies. The code conventions are from a different era. The compliance requirements have evolved, but the system hasn’t been audited against them. Nobody touches it because the cost of understanding it now exceeds anyone’s bandwidth.

Each of these decisions was individually reasonable. Together, they created a system that was simultaneously critical and unmaintainable.

Then I opened the batch jobs.

They were SSIS packages. DTSX files, XML-based workflow definitions from Microsoft’s SQL Server Integration Services framework. Microsoft’s ETL toolchain from an era when data processing meant drag-and-drop workflow designers and XML configuration files that could run to thousands of lines. Most engineers under forty have never seen them. Most engineers over forty have tried to forget.

And here was the turn. It wasn’t just that the team had avoided the system. Microsoft had effectively walked away from it too. SSIS was in maintenance mode: no active development, no meaningful updates, a dwindling pool of engineers who knew how to work with it. The technology itself was deprecated.

The engineers who avoided this system weren’t being irrational. They were looking at code written in a framework that even its creator had moved on from, processing compliance-sensitive financial data, with no tests and no documentation. The rational response was exactly what they did: don’t touch that.

The Rewrite

The instinct with a system like this is to rip and replace. Throw it away, build something modern, move on. That instinct is wrong, specifically because you can’t describe what the system does.

When there are no tests, no documentation, and no one who built it, the system’s behavior is defined only by its output. You don’t know the edge cases. You don’t know the special handling. You don’t know which apparent bugs are actually relied upon downstream. A rip-and-replace effort would be building against assumptions, not against a spec.

So step one wasn’t writing new code. Step one was TDD, but inverted. Instead of writing tests for behavior we wanted, we wrote tests for behavior we observed. Run the batch job with known inputs. Capture the output. Encode that as a test. Repeat.

Each test was a step deeper into terrain nobody had mapped.

Some tests revealed logic that made immediate sense. Others revealed behavior that seemed wrong but turned out to be correct, edge cases in billing reconciliation that the original engineers had handled but never documented. A few revealed genuine bugs that had been silently producing incorrect results for years. The tests didn’t just validate. They excavated.

Once the test suite existed, it became a spec. Now we could rewrite methodically. Replace one batch step at a time. Run old and new implementations in parallel. Compare outputs. When they matched, and the test suite stayed green, move on to the next step.

That is the starting point for legacy modernization when the trail has gone cold: recover the system’s behavior before deciding what to replace. Tests give the team evidence to work from instead of asking them to trust a new implementation on faith.

The result: processing time went from one hour to forty-five seconds. An 80x improvement.

I’ll resist the urge to over-explain. The speedup was real, but the number by itself doesn’t tell you much. The next section does.

Beyond the Speedup

80x gets attention. It was the least important outcome.

Bugs reaching production dropped 40%. That came from two changes: the test suite we built during the rewrite, and the shift to trunk-based development. Engineers could now make changes, run tests, and know whether they’d broken something. The system went from “don’t touch that” to “change it and verify.”

We hired two junior engineers and mentored them into a system that had previously repelled everyone. This mattered more than it might sound. If a modernized system still requires senior specialists to maintain, you haven’t really modernized; you’ve just moved the dependency from one set of people to another. The fact that juniors could contribute, ship changes, and understand the codebase was proof that the system had become legible.

The goal was to clear the trail so the team could hunt on their own.

The system became observable and testable. You could see what it was doing and verify changes before they reached production. The cost of modification dropped from “existential risk” to “normal engineering work.”

The real transformation was legibility, not speed.

The ROI of Modernizing “Working” Systems

The batch job “worked.” It completed every night. It produced output. The business had adapted to its hour-long runtime. Nobody complained.

This is the hardest case to make for modernization. Broken systems get fixed because there’s an incident. Slow systems get optimized because someone with authority gets frustrated. But systems that work, slowly, riskily, on borrowed time, are easy to leave alone. There’s no trigger. No burning platform. No event that forces action.

The degradation made the case even harder, paradoxically. A system that suddenly breaks demands attention. A system that takes sixty-two minutes instead of fifty-eight doesn’t. The processing time was a leading indicator nobody tracked. Each month it ran a little longer, and each month the absence of a hard failure reinforced the decision to leave it alone.

But the hidden costs were real. On-call engineers carried the burden of a system they couldn’t debug. Compliance exposure accumulated as regulations evolved and the system didn’t. Hiring suffered because the domain repelled engineers who looked at the stack and saw technology they’d never choose to work with. And every month the system ran, the cost of eventually changing it increased.

Here’s the framework I’d offer engineering leaders evaluating whether a “working” system needs modernization. Consider a rewrite when all four conditions apply:

No tests. You can’t verify what the system does, which means you can’t safely change it. Every modification is a gamble.

No original builders. The people who wrote it are gone. The understanding of why the system behaves the way it does left with them.

Deprecated technology. The framework, language, or platform is no longer actively developed. The talent pool is shrinking. Support is disappearing.

Compliance-sensitive data. The system touches financial, healthcare, or personal data subject to regulatory requirements that have evolved since it was built.

If you have all four, and you’re seeing silent degradation like growing processing times that nobody’s measuring, you’re already past the trigger point. The cost of action feels high, but the cost of inaction is compounding every month.

SSIS generalizes beyond this one system. Every organization has something like it: a system built on technology that was current when it was designed, now deprecated or abandoned. The engineers who could maintain it are retiring. The talent pipeline has dried up. And the system still “works,” which is exactly why nobody fixes it until it doesn’t.


Key Takeaways

“Don’t touch that” is a symptom, not a culture problem. When there are no tests, no documentation, and no one who understands the system, avoidance is a rational risk calculation. Fix the conditions, not the behavior.

Deprecated tooling compounds neglect. The SSIS packages weren’t just unmaintained by the team; they were abandoned by the vendor. Technology that even its creator has walked away from carries risk that grows even if nothing in your codebase changes.

TDD is archaeology before it’s engineering. When you can’t describe what a system does, tests written against observed behavior become the spec. Understanding the system through its tests isn’t a compromise; it’s the only honest approach.

The headline metric isn’t the real win. 80x is dramatic. But 40% fewer production bugs, a team that can change the system without fear, and junior engineers contributing to code that previously repelled everyone. That’s the actual transformation.

The framework for “modernize or leave it.” No tests + no original builders + deprecated technology + compliance-sensitive data = rewrite. Add silent degradation (processing times growing month over month with nobody tracking them) and you’re already past the point where waiting is the safer option.


Sitting on a legacy system nobody wants to touch? This is what The Chase looks like: the execution phase where we embed with your engineers, capture behavior in tests, and modernize step by step. Ownership transfer is part of the work, so your team can maintain what follows. Let’s talk about what it’s actually costing you.