Software Projects are Like Living Organisms

Şadi Elaşkar
6 min readNov 20, 2023

--

A common misconception about software projects, in my experience, is to consider them as static objects.

“We developed and deployed this small service. Now, we can forget about it and go on with other tasks.”

“We added this feature to our app. Maybe we should hire more people to add more of these faster.”

“X feature was developed years ago. It has been working fine since then. No need to worry about it at all.”

These are perhaps the most obvious indications of troubles coming ahead 🤷 Because, they disregard the never-ending changes to dependencies (of the software application) which people sometimes fail to recognize. Below is an unexhaustive list of those dependencies.

  1. The frameworks and programming languages
  2. Development tools (IDEs, compilers etc.)
  3. Developer skills
  4. Operating systems, hosting options
  5. Hardware, most importantly processor architecture (e.g. x86, 64-bit, ARM, ARM64)
  6. Community and professional support
  7. Internal or external services integrated, libraries used

So on and so forth. None of these are static. And most of them evolve (or die out) one way or another. How could a piece of software withstand those changes, unless its lifetime and maintenance during that period are carefully planned?

Just like living organisms endlessly needing to regenerate at the cellular level (and above) — so that they can replace old, deformed, damaged components — codebase of a software application needs to regenerate in every level, too.

It should bother a manager, if a component has been working well and untouched for a long time. It means it gets older than other parts of the software. It means it is not keeping up with the advancements which newer parts of the software enjoys. Result is a fragmented codebase.

Do you plan on deprecating that untouched component? If not, why would you neglect it like that?

Living organisms couldn’t stay alive, have they not being regenerating and adapting to changes in their environment, neither could your software. And you wouldn’t neglect your liver or spleen (given that you are a responsible person), if they fail to function as usual. Why would you neglect a software application that is essential for your business or community?

In my opinion, fragmented codebase is no different than multiple organ failures. And they must be addressed with utmost urgency.

Granular evolution makes it only more painful

General preference among big companies and their large software projects is to replace their ‘legacy’ applications, when they get old and hard to sustain.

But it is typically painful for companies of any size to develop replacement software. The challenges they face should be familiar to anyone who has seen such a transformation project.

There is one widely overlooked aspect I especially want to emphasize. And that is the integration which new and old versions of the software will almost inevitably need to implement.

You may select the most suitable technology stack, adopt state-of-the-art architecture and practices, hire good talents; this inevitable integration between two generations of your software will plague the new one, not only until the legacy one is decommissioned, but long after that. This will ensure the quality of the new product will be sub-optimal. It will be born sick, if we stick to the analogy.

Ultimately, enormous investment will be made, disruption to service of some magnitude will be endured just to get a sub-optimal product.

Unfortunately, this may not be obvious to some of those in charge of planning these transformation projects. While worrying about things like: “When is the best time for this transition? Can we do this within our capacity? How long will it take?”, the problem I mentioned can be easily overlooked.

To borrow perhaps the most iconic line from the original Jurassic Park movie:

…but your scientists were so preoccupied with whether or not they could that [reviving species of dinosaurs], they didn’t stop to think if they should.

Since transformation projects are a commonplace thing in the industry, it is understandable, if a manager finds it natural to replace the aging software without putting too much thought into whether they should do so.

Here I say: What if the software never gets to become ‘legacy’ in the first place, so that you don’t have to replace it?

The molecular machinery of living organisms is non-stop. It is challenging to halt it temporarily (like freezing) and then get it going again. Maintenance of a software project should be considered the same. It should be tedious and non-stop. However, building a replacement software, while putting the existing one in life support is the opposite of it. And I find this approach fundamentally flawed.

Software projects are alive

Being alive is one of those things for which we don’t have a proper definition, much like intelligence. Because, it is difficult to define a clear boundary between life and death. (Check out this awesome video from Kurzgesagt on the topic.)

What we can define is a set of common properties for living organisms.

Here I will try to explain why I think any sufficiently long-term project can be considered alive.

If you need, take a second to look at this page which explains the common properties of life. I think software applications can be considered alive, because they share the following properties:

  • Order: It is perhaps the easiest one to explain. You need to establish a good structure in your codebase and maintain it, otherwise you will end up with spaghetti code, regardless of the age of your software.
  • Adaptation: Software applications evolve through adaptation to changes to the business purpose they serve (commercial or not). The ones which fail to achieve this will be considered a failed project.
  • Homeostasis: Just like living organisms need to maintain their internal temperature, water and pH levels etc., applications need to maintain a healthy level of workload, CPU and memory utilization, storage space etc. You don’t want it to be suffocated with lack of resources, but also not be drowned with abundance of them either, because it would be wasteful.
  • Reproduction: It is easy to spin off a software project to as many variants as needed. Companies sometimes prefer this option for sub-branding etc. And just like in nature, some of the offsprings may get nurtured and keep developing, while others die out. (As a side note here, I witnessed many times that managers get tempted by this ease of cloning and overlook the difficulties of nurturing multiple offsprings. Fixing or improving the same thing in multiple clones is not fun for anyone and usually gets neglected.)

For the sake of brevity, I don’t go on with explaining the similarities with remaining properties, i.e., energy consumption, growth/development, regulation, and response to stimuli. Because I think what you have seen should be enough to take the comparison seriously 🙂

Technical debt is real debt

And it should be in accounting books like any other debt. I will not go into much detail, because this is a subject for another post. However, there is one thing I want to highlight here.

If you don’t have a sizable team to maintain your entire codebase to high standards, you are in deep technical debt in my opinion. When you let the codebase outgrow the capability of your team, you carry a debt which your business will eventually need to pay back.

Healthy amount of debt is okay or even necessary in any type of business, as long as you are aware of the actual depth of it. I think magnitude of technical debt, more often than not, is underestimated. The consequence is ever increasing hardship of adding new code, delivering new features. As in the famous boiling frog apologue, this hardship itself also gets harder to see for insiders.

In time, the ability to quickly adapt to external changes may degrade to a level where the business has significant competitive disadvantage. Just like an endemic plant which cannot keep up with severe changes to surrounding climate will have no option but to die out, such businesses will inevitably be dissolved, or absorbed by larger organizations.

Summary

I believe, throughout the post, I effectively pointed out the common mistakes I see and the alternative approach that needs to be adopted by software project managers and development teams. But, I prepared a bulleted list as summary anyway:

  • Educate stakeholders on the negative impact of technical debt. Here is a short story to help you.
  • Have people continuously refactor existing code to improve code quality.
  • Keep rarely visited parts of your code up-to-date with the rest of your project. Eliminate fragmentation. E.g., “Look, folks. We developed this integration almost three years ago. Even though it is working fine, in terms of code quality, it is lagging behind. We must refactor it as soon as possible. Otherwise, it will become too difficult to maintain. Let’s prioritize this. “
  • Keep your tech stack up with advancements in the industry. Upgrade framework versions and tools without significant delay.
  • Don’t fall into trap of the ideas listed in the beginning. Resist the temptation of delivering more features hastily.
  • Try not to rush into fixing bugs that affect complex parts, for which you have workarounds. Fixing them swiftly without proper care will probably lead to new bugs. You will end up in a never-ending loop of bug fixing. Instead, accept them as known issues until you have enough time to comprehensively address the issue.

--

--