Managing Software Debt – article

Managing Software Debt
Continued Delivery of High Values as Systems Age

Many software developers have to deal with legacy code at some point during their careers.  Seemingly simple changes are turned into frustrating endeavors.  Code that is hard to read and unnecessarily complex. Test scripts and requirements are lacking, and at the same time are out of sync with the existing system. The build is cryptic, minimally sufficient, and difficult to successfully configure and execute. It is almost impossible to find the proper place to make a requested change without breaking unexpected portions of the application.  The people who originally worked on the application are long gone.

How did the software get like this?  It is almost certain the people who developed this application did not intend to create such a mess.  The following article will explore the multitude of factors involved in the development of software with debt.

What Contributes to Software Debt?

Software debt accumulates when focus remains on immediate completion while neglecting changeability of the system over time. The accumulation of debt does not impact software delivery immediately, and may even create a sense of increased feature delivery. Business’ responds well to the pace of delivered functionality and the illusion of earlier returns on investment. Team members may complain about the quality of delivered functionality while debt is accumulating, but do not force the issue due to enthusiastic acceptance and false expectations they have set with the business. Debt usually shows itself when the team works on stabilizing the software functionality later in the release cycle. Integration, testing, and bug fixing is unpredictable and does not get resolved adequately before the release.

The following sources constitute what I call software debt:

  • Technical Debt[1]: those things that you choose not to do now and will impede future development if left undone
  • Quality Debt: diminishing ability to verify functional and technical quality of entire system
  • Configuration Management Debt: integration and release management become more risky, complex, and error-prone
  • Design Debt: cost of adding average sized features is increasing to more than writing from scratch
  • Platform Experience Debt: availability and cost of people to work on system features are becoming limited

Software Debt Creeps In

Figure 1.1: A relatively new system with little debt accrued.

Figure 1.1 displays a system that has minimal amount of software debt accrued. A few low priority defects have been logged against the system and the build process may involve some manual configuration. The debt is not enough to significantly prolong implementation of upcoming features.

Business owners expect a sustained pace of feature development and the team attempts to combine both features and bugs into daily activities, which accelerates the accrual of debt. Software debt is accruing faster than it is being removed. This may become apparent with an increase in the number of issues logged against the system.

Figure 1.2: An aging software system slowly incurs significant debt in multiple functional areas.

As a system ages, small increments of software debt are allowed to stay so the team can sustain their velocity of feature delivery. The team may be complaining about insufficient time to fix defects. Figure 1.2 shows a system that has incurred software debt across all functional areas and components.

At this point, delivery slows down noticeably.  The team asks for more resources to maintain their delivery momentum, which will increase the costs of delivery without increasing the value delivered. Return on investment (ROI) is affected negatively, and management attempts to minimize this by not adding as many resources as the team asks for, if any.

Even if business owners covered the costs of extra resources, it would only reduce the rate of debt accrual and not the overall software debt in the system. Feature development by the team produced artifacts, code, and tests that complicate software debt removal. The cost of fixing the software debt increases exponentially as the system ages and the code-base grows.

Figure 1.3: The aging system has accrued significant debt in all functional areas and components.

Software debt in the system continues to accrue over time, as shown in figure 1.3. At this point, new feature implementation is affected significantly. Business owners may start to reduce feature development and put the system into “maintenance” mode. These systems usually stay in use until business users complain that the system no longer meets their needs.

Managing Software Debt

There are no magic potions for managing software debt. Software can accrue debt through unforeseen circumstances and shortsighted planning. There are some basic principles that help minimize software debt over the lifespan of the product:

  • Maintain one list of work
  • Emphasize quality
  • Evolve tools and infrastructure continually
  • Always improve system design
  • Share knowledge across the organization
  • And most importantly, hire the right people to work on your software!

Maintain One List of Work

One certain way to increase software debt is to have multiple lists of work. Clear direction is difficult to maintain with separate lists of defects, desired features, and technical infrastructure enhancements. Which list should a team member choose from? If the bug tracker includes high priority bugs, it seems like an obvious choice. However, influential stakeholders want new features so they can show progress to their management and customers. Also, if organizations don’t enhance their technical infrastructure, future software delivery will be affected.

Deployed software considered valuable to its users is a business asset, and modifications to a business asset should be driven from business needs. Bugs, features, and infrastructure desires for software should be prioritized together on one list. Focus on one prioritized list of work will minimize confusion on direction of product and context-switching of team members.

Emphasize Quality

An emphasis on quality is not only the prevention, detection, and fixing of defects. It also includes the ability of software to incorporate change as it ages at all levels. An example is the ability of a Web application to scale. Added traffic to the web site makes performance sluggish, and becomes a high priority feature request.  Failed attempts to scale the application result in a realization that the system’s design is insufficient to meet the new request. Inability of the application to adapt to new needs may hinder future plans.

Evolve Tools and Infrastructure Continually

Ignoring the potential for incremental improvements in existing software assets leads to the assets becoming liabilities. Maintenance efforts in most organizations lack budget and necessary attention. The International Organization for Standardization (ISO) standardizes on four basic categories of software maintenance in ISO/IEC 14764[2]:

  • Corrective maintenance – Reactive modification of a software product performed after delivery to correct discovered problems
  • Adaptive maintenance – Modification of a software product performed after delivery to keep a software product usable in a changed or changing environment
  • Perfective maintenance – Modification of a software product after delivery to improve performance or maintainability
  • Preventive maintenance – Modification of a software product after delivery to detect and correct latent faults in the software product before they become effective faults

Most maintenance efforts seek to prolong the life of the system rather than increase its maintainability. Maintenance efforts tend to be reactive to end user requests while business evolves and the technology decays.

To prevent this, attention must be given to all four categories of software maintenance. Budgets for software projects frequently ignore costs for adaptive, perfective, and preventive maintenance. Understanding that corrective maintenance is only part of the full maintenance picture can help an organization manage their software assets over it’s lifespan.

Improve System Design Always

Manage visibility of system design issues with the entire team. Create a common etiquette regarding modification of system design attributes. Support the survival of good system design through supportive mentoring, proactive system evolution thinking, and listening to team member ideas. In the end, a whole team being thoughtful of system design issues throughout development will be more effective than an individual driving it top down.

Share Knowledge Across the Organization

On some software systems there is a single person in the organization who owned development for 5 years or more. Some of these developers may find opportunities to join other companies or are getting close to retirement. The amount of risk these organizations bear due to lack of sharing knowledge on these systems is substantial.

Although that situation may be an extreme case of knowledge silos, a more prevalent occurrence in IT organizations is specialization. Many specialized roles have emerged in the software industry for skills such as usability, data management, and configuration management.  The people in these roles are referred to as “shared resources” because they use their specialized skills with multiple teams.

Agile software development teams inherit team members with specialized roles, which initially is a hindrance to the team’s self-organization around the work priorities. Teams who adhere to agile software development values and principles begin to share specialized knowledge across the team, which allows teams to be more flexible in developing software based on priorities set by business. Sharing knowledge also reduces the risk of critical work stoppage from unavailable team members who are temporarily on leave.

Hire the Right People!

It is important to have the team involved in the hiring process for potential team members. Teams will provide the most relevant skills they are looking for, thus, allowing them to review and edit the job description is essential. Traditional interview sessions that smother candidates with difficult questions are insufficient in determining if the candidate will be a great fit. Augmenting the interview questions with a process for working with the candidate during a 1 to 2 hour session involving multiple team members in a real-world situation adds significant value to the interview process. Before hiring a candidate, teams members should be unanimous in the decision.  This will increase the rate of success for incorporation of a new team member since the team is accepting of their addition.

Another significant hiring focus for organizations and teams is placing more emphasis on soft skills than technical expertise. I am not advocating ignoring technical experience. However, it is critical in an agile software development organization or team to have people who can collaborate and communicate effectively. Soft skills are more difficult to learn than most technical skills. Look for people who have alignment with the hiring team’s values and culture.

In Summary

As systems age they can become more difficult to work with. Software assets become liabilities when software debt creeps into systems through technical debt, quality debt, configuration management debt, design debt, and platform experience debt.

Applying the six principles in this article will lead to small changes that over time will add up to significant positive change for teams and organizations.  The goal of managing software debt is to optimize the value of software assets for our business and increase the satisfaction of our customers in the resulting software they use.

References

  1. Ward Cunningham – “Technical Debt” – http://c2.com/cgi/wiki?TechnicalDebt
  2. “ISO/IEC 14764: Software Engineering — Software Life Cycle Processes — Maintenance” – International Organization for Standardization (ISO), revised 2006
Be Sociable, Share!

13 thoughts on “Managing Software Debt – article”

  1. Nice article. I remember having to try and decypher someone elses code whilst backing up every single change and thoroughly testing it before moving onto another change.

  2. Excellent article. I read this having recently discussed the ‘broken windows’ metaphor used in Andy Hunt and Dave Thomas’s “Pragmatic Programmer”.

    As a software house that delivers bespoke software solutions to corporate customers we grapple with the issue of managing ‘software debt’ in the context of getting the customer to understand the issue enough to justify the budget for re-factoring. This is not always an easy task.

    Our development team continue to explore the best ways to enact the principles of agile development and translating that into a commercially viable offering.

    Experience plays a big part in judging whether there is sufficient time in the schedule of a project to allow re-factoring to occur even if the benefits and long term advantages are clear.

  3. Very interesting article. Especially how you listed Technical Debt as a sub category of Software Debt alongside other aspects of Software Debt (such as Quality Debt and Design Debt etc.)

    Is this your own innovation or do others use a similar categorization? Up until now I have considered Software Debt and Technical Debt to be synonyms and included the other aspects within.

    Except I think that Configuration Management Debt and Platform Experience Debt are more symptoms of Software Debt rather that components, or causes of it.

    Also thought provoking is the idea of listing technical debt payback tasks in the same list as all other tasks, which implies, to me at least, that we can quantify it in the same way as the other tasks for example as story points.

    I look forward to your further posts on the topic.

  4. This is a great article. Our team is reviewing our technical debt and trying to be more proactive in preventing it from piling up. I think part of what leads to this debt, at least in our case, was an over-reliance on the idea that the pre-existing code in our system was “already tested”. It ended up having to be modified heavily.

    So, we ended up with a Regression Test Suite Debt, in that we had no automated regression tests and no performance / load tests against which to measure the system at the end of a long big-bang rewrite.

    We took steps to correct this by introducing automated testing using Selenium and web load tools.

    However, convincing reluctant management who already see a project over-budget and running longer than they wished is not an easy task. Eventually we adopted Scrum and other agile practices to help us prioritize on delivery requirements.

    When it comes to debt that is piling up, you really have to operate on principle. This means you probably have to “draw a line in the sand” when you know that the debt is too large and it must be addressed NOW, before disaster occurs later.

    This does not mean you do not negotiate, far from it. However, you must set forth the principle that you, as a technical person, will not proceed with decisions made by someone else that you feel are ill-advised and worsen the debt. If you ever feel pressured into into making decisions to continue piling up debt, think about this:

    1) If you accept the decision and proceed, and utter failure occurs as you predicted, does it make it any better that it wasn’t your decision in the first place?

    The likely answer is no, it does not make it better. There is very little satisfaction in seeing a failure occur that you had anticipated and failed to prevent, regardless of whether it’s your decision of somebody else’s.

    2) If you argue the decision and insist that the debt must be paid down, what is the worst that could happen?

    Will they fire you? They likely will not. If they do, you’re probably better off elsewhere anyway if you’ve been warning of the debt for a long time and they continue to ignore it.

    3) Finally, sometimes you can remind them that the reason the debt is high is that they made decisions early on not to slow down, knowing that the debt would have to be removed later. But, make sure they understand that THERE IS DEBT. If they don’t even believe that there is debt, then your task is more difficult.

    Finally…

    After all is said and done, the team as a whole is responsible for the quality of a system, not one individual. If a team denies responsibility and blames “management decisions”, then the team has not tried hard enough or has not been smart enough to solve the problem.

    Development, in groups larger than one, is a team sport, and that is why the Scrum metaphor works well. It is not easy, and it requires constant communication and attention, but

  5. Hi Chris–

    Great article! I’d like to reprint this post on pmboulevard.com in our January 19 issue. Please email me to talk specifics.

    Best Regards,

    Jen Girdish

  6. One thing I do not understand is SCRUM prescribing about “RIGHT or highly skilled people” as part of scrum to be more effective. I personally feel that SCRUM/AGILE is indirectly encouraging the technical rascism among the software world. I beleive who ever working, are very well qualified and if they are not qualified, they wont be hired in the first place.
    If one has highly skilled people to start with, then why do we need to follow scrum but not any other frameworks. Highlly skilled/right people will always succeed no matter what framework they use. So, we need to stop the scrap about “Right/highly skilled people” requirement/prescription as part of Agile/Scrum. Though scrum is good but it indirectly INVESTs in creating divisions in the software industry too.

  7. I agree if your perspective is right in terms of only 1 “right” type of person for all software projects. Maybe I did a poor job of discussing that right means, in this case, for the job at hand. Java people working on Java projects. I did not mean a superior software developer that is amazing in all aspects of all domains and platforms.

  8. There is also “testing debt”.

    But sometimes “debt” is too clean a metaphor. Brian Foote’s paper on “Big Ball of Mud” mentions software shanty towns, and I’ve seen code that reminded me of “slums”. (More on software slums here: http://goo.gl/Jsl9P)

  9. Yes, I have read that paper and liked its use of shanty towns. I think I reference it in the upcoming Managing Software Debt book. Should be out soon (any day). As for “testing debt”, I bucketed this under Quality Debt as the break/fix mentality.

    Hope that we are able to meet and discuss this in more detail sometime.

Leave a Reply

Your email address will not be published. Required fields are marked *