Horror Story: How Software Projects Die Through Lack of Maintenance

A prompt: Write a software project horror story in six words.

“Needs one update. Rest can wait.”

There are few phrases that represent the death knell of a software project more than that, or some variant of that. I’ve seen a pattern over the years where a project starts as the golden child full of promise, grows into maturity and use, and finally is ignored and barely supported until, finally, it’s too expensive to keep running, leading to project death.

Here’s how that goes:

Project Life – Birth

When a project begins, it usually gets a lot of attention within its organization. It holds promise and all the dreams of what it might be, and many of those are often realized. The company allocates resources and support, and the organization is enthusiastic about the swift progress.

This is the part of a project lifecycle we want to think about, but most of the calendar life of the project isn’t spent here.

Project Life – Teenage Years

After achieving MVP status, the project will still feel good to most of the participants. It’s running smoothly and the team is still around. Usually, through the mature operation phase, the team (though probably smaller than at the start) has enough capacity to make small updates and upgrades, feature requests can get in, new reports can be built, etc.

But after a while of this, it seems like organizations get comfortable.

Project Life – A Productive Career

Eventually, the original team rotates off of the project. That might be because they’ve been reassigned within the organization or because the original development team simply left. Or perhaps an outside firm built the project and the organization can no longer justify a full-time contract.

When this happens, typically no alarm bells go off in the organization because things seem to be going well.

Except… things aren’t going well.

What I’ve described above should be terrifying. I’m describing the slow loss of institutional knowledge. At this point, the organization no longer has the expertise to maintain the software or perform updates. You may be able to hire someone who (for example) knows Ruby on Rails. But you can’t hire someone that knows your Ruby on Rails app, and that is a big liability.

A Project Health Scare

I’ve seen organizations coast along like this for years. The software is fine, no need to worry about it. Sure, Sally is leaving the company, but we’ll just offshore the work for the next point release. No worries.

This works fine, until it doesn’t. Back to that story at the top: eventually, the customer will just need “that one feature.” They just want some single small update. Just enough to get us through that trade show. Just enough to close out the fiscal year. Don’t invest more time fixing it than you have to — just get it done so we can move on, and we’ll budget for more project maintenance next year.

Thus begins the inexorable slide to an ignominious decommissioning.

This is a common scenario: an app has worked well for some time and now needs a small update. Maybe it’s for styling, maybe for security patches, whatever. But this update has to happen, and the organization doesn’t have the expertise to do it anymore.

This is a decision point.

Project Death

Usually what happens is that the new developer, under significant pressure, fixes the glitch, and the stakeholders are happy. What stakeholders don’t see, though, is that typically the developer wouldn’t have gotten enough time to understand the system architecture and the best way to make the change. They may not have time to set up a full development environment. They certainly haven’t applied security fixes. The developer just “fixed the glitch” and moved on, as instructed.

I’ve been that developer before and made those bad fixes. I’ve been open about it, but that quality of work is often what’s requested, even “against medical advice,” so to speak.

This is by far the most common path I’ve seen organizations take. This is how projects die. Once you abandon your institutional knowledge, it becomes very hard to maintain the application:

  • The requests for “just one small fix” accumulate.
  • Edge cases are forgotten, and these small fixes may often miss them.
  • Test suites fall into disuse. They don’t work on new machines or with updated tools, or they take too long to run for the “small fixes.”

All these things accumulate in a death by a thousand cuts. Each fix is more expensive. Each time you touch one thing, something obscure breaks, because they’re related, but your current dev team no longer knows how. Quality falls, regular patches are missed.

At this point, you’ve created a hard hole to dig yourself out of, even if you dedicate the resources needed to do so. That’s because the team has forgotten so much and so much of the code has been changed, duct-taped, and jury-rigged.

Project Maintenance: Regular Exercise to Stay Healthy

Instead, before you get to the point of accumulated small update pains, you should pause. The first time you find yourself pulling up an old system for “one last tweak,” make a decision to continue or not. Ask yourself:

  • Is the system still being used? If you want to be sure about this, turn it off for a few weeks. You’ll know if it’s still being used. If turning it off makes you nervous… well, why?
  • Can you point to a specific system to replace it? Can you log into it?

If the system is still being used and there’s no replacement already in progress, then you’re going to need to keep the now-legacy system going. If not, and you do decide to decommission the old system, decide intentionally before it falls into disrepair.

On the other hand, if you decide you want the system to stay living, the most important thing to do is to really commit to project maintenance. This doesn’t need to be a lot, but it still should be a real commitment.

Obviously, the necessary commitment will vary with the project, but a typical order of magnitude would be a pair for one month out of each year.

That’s enough time for someone familiar with the tech stack to ramp into it. It’s frequent enough to keep platform and dependencies mostly up to date and make sure the app and tests run easily on the now-current hardware. It’s enough time to do some project maintenance work and some enhancements or fixes. And most importantly, it continues to maintain the institutional knowledge about the project, what it’s for, and significantly increases the odds that there’ll be someone who remembers how to make whatever “one small update” you need.

Software, like legends, dies when it’s forgotten.