Unlocking Legacy Tech Stacks

Unlocking Legacy Tech Stacks_Julian Flaks_EQengineered.jpg

Sometimes tech debt becomes big enough that it becomes its own story to the business.  More often it's a hidden story that can mistakenly be overlooked; lowering it is always a win, and if enough time is going to be lost in a project due to the frustrations, the fix can even pay for itself.

Let's start with the obvious: what is tech debt?

Ward Cunningham coined the term and has been quoted variously as likening it to taking on a loan in the interest of taking a short-cut.  Failure to repay the loan further down the line leads to successive problems and greater amounts to pay back.

As the term has grown in usage and understanding, engineering organizations have come to realize that some degree of technical debt is usually inevitable.  Rather than the much-used analogy of taking on credit card debt as a short-term solution, this broader sense might be better thought of as having a mortgage - an intentional and considered situation with long term implications both good and bad.

What's also become increasingly true is that technical debt also accrues from a lack of upkeep.  Where the term once belonged to issues coming from poor coding practice or a core misidentification of a domain concept, many organizations have watched as ongoing tech-rot has turned once-loved libraries and technology choices into an unfair accumulation of technical debt.  Tools like static code analysis cannot demonstrate this debt, because at the time it was adopted, there really was no identifiable problem, save perhaps an overly tight coupling between architectural layers.

Unfortunately, a lack of culpability for this legacy technical debt does nothing to reduce the cost to organizations.  Some of these costs will show up as:

  • Estimates climbing higher for the same work

  • Paying specialists to fix the problems

  • Becoming the main bugfixer of a community solution

But the costs of legacy technology dragging you down can be more hidden:

  • Clients skipping your product because of that outdated browser plugin

  • Developers researching legacy technology and not gaining skills you'd like them to have

  • Your tech stack becoming a put-off during hiring

  • Retention becoming harder as developers leave out of self-preservation

  • A lack of community solutions and advice - and an ensuing quality drop in decisions you make

  • Short-term-ism entering design choices, awaiting the day things are re-written

  • Less satisfactory outcomes as you settle for what's practical

One often hears the gut reaction to refactoring legacy debt: why not just rewrite it all.  There are times this is a good idea, but it's worth always bearing in mind that the new version runs risks getting to market that the old one didn't - the minimum viable product is often 100% of the functionality, without the supporting feature documentation to back the effort up.

Some successful strategies for incrementally re-architecting: 

  • New client-side UIs using existing or partially new REST endpoints

  • Presentational middleware to convert data formats

  • Joint navigational structures to allow new and old parts of an app to share real estate

  • Back-end to back-end communication between old and new stacks

  • Injection mechanism proxies to share objects

More creative solutions to fixing legacy technical debt run the risk of adding extra tech debt by themselves, but done correctly they can be staged, allowing new work to begin in an ideal way and leaving the conversion of old code free to be scheduled with feature enhancements. 

Julian Flaks