This article discusses how long-term survival rate of internal software projects can be improved. The primary audience are senior software engineers and engineering managers working in medium to large organizations.
When searching for “maintainable software”, many articles (, , ) focus on good coding practices. And certainly, good naming conventions, readable code, continuous integration, unit testing, … are all very important. However, I feel that many discussions implicitly assume a caring person who is motivated and capable to take care of the required maintenance indefinitely. I found that this is often not the case. In a larger organization with considerable churn and regular changes in direction, it quickly happens that projects, which were once a great success, quickly fall between the cracks.
In this article I motivate a discussion about Software Survivability which I feel should be considered in addition to existing ideas on maintainability. In the following article I will focus on the created value of a software project and why the effective communication of its value is so critical. Having projects who are successful in the long-term are generally great return-on-investment (ROI) for the company as they generate a lot of value from them. Starting such projects and keeping them alive is a widely recognized achievement that distinguishes engineering managers and senior software engineers.
This article is written from the perspective of an infrastructure software engineer. It focuses on projects that are used internally to build the end-user product or are used as libraries. These projects but are generally not directly visible to the end-user.
Where Maintainable Code is not Enough
One of the main ideas of maintainable code is that it keeps the costs for changes low. It does so by making code easy to understand, easy to change, and easy to test. However, in practice this idea is often only concerned with the code written for the project. Often little attention is paid to the supporting infrastructure such as the build pipeline and dependencies.
As the company-wide build system evolves, this process requires difficult manual work and testing. While good tests help with ensuring correctness within the project itself, the integration with other projects up and down the dependency tree can be tedious. For intricate builds (e.g. C++ with many target architectures) a build system change quickly becomes a multi-week undertaking requiring careful synchronization with the world around.
Deprecation of dependencies is another example – in particular for software projects that rely heavily on a bespoke framework. The person tasked with maintaining the project needs to have a good understanding of the big picture in order to update it efficiently. In practise, frameworks also tend to leak into unit tests and require rewrites there as well.
In these situations the maintainer often have to decide between the options: (i) abandon the project (“it is not worth the effort”), (ii) rewrite instead of fix, or (iii) put in the work to keep it running. The first choice is tempting when there is little communal understanding of its value and the team is generally overwhelmed. The second choice is motivated by heightened expectation and recognition for new, original code. This is even more tempting when the history of the project (and the hardness of the solved problem) are not well understood by the new team. The third choice is often hard to sell, because while the costs (weeks) are often clearly visible, the value tends to be more fuzzy.
Such dynamics develop when the projects original champion (advocating and defending it in the beginning) is no longer the person responsible for it. This can happen to single persons when they switch teams or leave, but it also applies to larger groups where there is a shift of focus or larger reorgs in the company. The new person taking over often does not actively choose it, and more often than not the project’s success relies on their goodwill.
Raising a Software Project for Survivability
I think one of the most important aspects is identifying the value that the software project provides from the beginning and communicating that every possibility. There should be no status update that does not explain how recent changes create value. There should be no meeting with a partner team without both sides agreeing on the value created (or to be created). There should be no reports going up the chain that do not explicitly highlight the project’s value. The earlier in the project these discussion are had, the easier it is to have strong alignment and honest discussions.
Once the value of the project has been established and agreed it is important to document it. Documenting the rational, challenges, and wins of a software project are just as important as its technical aspects. This can happen as the project goes along as a private or semi-public diary. Regular status updates (weekly or monthly) are a great tool to get into this habit. Ideally, the documentation also highlights product launches, links to analytics queries, metric, and similar. These allow a person from the future to learn how to measure and communicate the value of the project. In particular, this then helps to demonstrate the value of keeping it running.
My rule of thumb for the survivability of an internal software project is: if all engineers are removed from their projects and have to pick new ones, are there any who would pick mine? This should ideally be true for some of your direct collaborators, your direct team, and partner teams. You quickly see that this depends on how well others understand the value of the project and are able to demonstrate it to others. Enabling others to advocate and defend the project is what makes them the next champion.
I hope this article helps to expand the perspective beyond code quality when talking about whether a software project will survive in the long-run. Only software whose created value is understood will maintained and only software that is maintained will survive. And at that point the maintainable code discussion comes in - primarily as a cost argument. Being even more drastic: if the understood value is high-enough, software will be maintained – because the company and people working on it benefit from doing so.
Why should one care personally? I find that reduction of software churn makes work more satisfying. It means that knowledge acquisition and smaller tweaks have higher ROI. Also, knowing that a software will be around a long time, motivates the improvement of developer experience and ergonomics. This is because maintainability then becomes a calculable and certain cost element that can be optimized. Finally, creating something that transcendences ones personal contribution is a great achievement and powerful motivator.