Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Re: RFC: Exploring Technical Debt

by whakka (Hermit)
on Sep 24, 2009 at 20:42 UTC ( #797313=note: print w/ replies, xml ) Need Help??


in reply to RFC: Exploring Technical Debt

You would probably think of developing a method of measuring technical debt (rather than a simple equation or model) because it must necessarily be project-specific, and the "true cost" of each item (ex. deferred refactoring) is best known by those that would implement them. Having experience with similar projects would aid in more accurate estimates.

Simplified, the problem can be stated: "Solving debt item D now would take N man-hours. D makes it X% longer to fix certain kinds of bugs on average.* We can expect to encounter these sorts of bugs Y times per year. The average expected time it takes to fix these bugs is Z man-hours. Given the staffing on this project I would weight this figure by W." You should similarly add the man-hours saved for implementing new features. D's per anum opportunity cost (in man-hours) is then the sum of X * Y * Z * W for all such bugs + (similar sum for new features). This can be thought of as future "earnings" for fixing D now.

It then becomes an intertemporal cash flow problem. You must consider the time cost involved to make the fix now versus how much time is involved in repayment for the future. You only consider those years you expect the project to be maintained (the longer the time the less important this estimate is). The ultimate comparison of each item should be the cost of fixing D now (N) vs. the present value of all future productivity losses from D in maintenance and new features (F). If N - F < 0 it's better to fix the problem now, otherwise we should shelve it for later, if ever.

To calculate F you determine a discount rate, a non-trivial task based on a variety of difficult to estimate factors. In general it's the necessary return on investment of paying developers now to be more productive in the future, plus risk (ex. bankruptcy risk of delaying a shipped product, risk of employee turnover, security risks, inflation risk, etc). It's difficult to do this simply and in a suitably general way. If developer time would otherwise go to adding new features on the same product, the value of those features should be used to calculate an internal rate of return on those features (based on an analysis of how much higher the product would sell for or how many more copies it would sell). Similarly, if they would otherwise go to another project, that project's marginal IRR should be calculated and used. Alternatively, the company's WACC may or may not be appropriate. Calculating F is now a matter of running an NPV algorithm in a spreadsheet.

Since each input is an estimate, it would be prudent to repeat this calculation using a variety of values for your estimates, picked based on how confident you are in them (how well their cost is known) and for worst-case scenarios. For example you may consider a steep discount rate if your company's survival is strongly determined by the success of your product as it's shipped in 4 months.

**Updated for clarity.

*X must be determined inside the technical domain, so consulting existing studies might be misleading.


Comment on Re: RFC: Exploring Technical Debt
Download Code
Re^2: RFC: Exploring Technical Debt
by jthalhammer (Friar) on Sep 24, 2009 at 23:32 UTC

    I think this is definitely on the right track. As you pointed out, the really hard part is devising a method for calculating the parameters in any such model. But for now, I'd like to put that aside and just focus on what the models might be.

    Actually, what I really want might be a bit less academic than a formal model. I'd like to see a discussion that relates more financial concepts and terminology to software development. If we consider "technical debt" as some kind of loan, then who exactly is the lender and who is the borrower? What part of is the principal and what part is the interest? How does the "interest" compound? How are the "funds" actually exchanged between parties. What are the incentives for the lender and borrower to enter into this transaction? How do lenders choose the right borrowers? What are the risks for either party? How do parties hedge those risks?

    Some of these questions seem to have intuitive answers at first glance, but I feel that they haven't been fully articulated yet. So as software developers, I think most of us really only have a superficial grasp of the "technical debt" concept. But I want to believe that our understanding can go much deeper than what we currently see in typical literature.

    I don't have the answers here, but I'm eager to facilitate the discussion.

    -Jeff

      I think to address the issue of terminology, the "debt" is simply all future productivity losses from "hacking" a short-term solution to a problem. You (the company or project owner) are "borrowing" from your developers' future productivity to increase their productivity today. Productivity (output/time) can be measured in value.

      In terms of a loan, the "principal" is the short-term productivity gains by hacking solutions. The "interest rate" is the percentage loss in future productivity or the added expense in percentage terms of maintenance. It may be fixed over time as fixing bugs and adding features is more expensive by some constant factor. It probably compounds over time though as hacks are built upon hacks (and therefore be a variable increasing rate).

      The interest is more important to medium- to long-term projects. It's also the explanation for why I read so often that salaried employees hate consultants setting up a system; the consultants are in essence borrowing from the future productivity of another companies' employees and yet they get to reap the short-term productivity gains in the form of getting paid for delivering on time - what a deal for them!

      As a framework for pricing the loan I suggested thinking about it in the reverse; rather than acquiring technical "debt" you are implicitly forgoing technical "investments" - spending time today to realize greater output per time in the future. This is opportunity cost, and it has value. The choice becomes whether or not to make the investment.

      Anti-regressive measures like refactoring in a sense have zero short-term productivity but positive long-term productivity. If short-term output is more important to a company then they have a higher discount rate and therefore losses in short-term productivity must be compensated by greater gains in long-term productivity.

      There are two types of risk - one affects the estimates of the cost of the loan (return on investment) and the other the discount rate (time value of money). For the former, a big risk is staff turnover, not just in terms of employment but at the project level. If the developers of a system leave after it ships, future productivity losses from such loans are likely to be far greater than retaining people with an intimate knowledge of the system. For the latter, start-ups have a higher bankruptcy risk and therefore a higher discount rate. There are business and economic risks as well, such as lost market share and shocks to the labor market.

      I don't think there can ever be a formal model since it's an impure science. My post was merely an outline of the required steps to perform a traditional financial calculus of the decision to take on a single debt item. It implied a lot of intermediate estimation and guesswork and for some loans it may not produce reasonable values.

      And it can be argued, no matter the method used, that it's impossible to capture the positive externalities that are realized by committing to best practices. Developers are people after all, and people are arguably more motivated by being in a culture that cares about quality work and low-level input.

      I had a thought on this early this morning when I was somewhat less than awake.

      Although there's no concept of separate lenders in technical debt, we can get something almost as good. When faced with the need to take on technical debt it might be possible to select among several solutions that have different interest rates.

      Imagine a problem that we don't have time to solve correctly, but a small amount of brainstorming produces two potential hacks. One is the nightmare you normally get in this situation. The other leaves some wiggle room for a few unit tests or some minor validation code that helps recognize edge cases.

      Even though this second solution still increases the technical debt in the system, it has a lower interest rate because it helps to point out the places where it makes maintenance harder.

      I have known good programmers who added some kind of trap code in a half-way solution to point out when boundaries were reached. This allowed writing simpler, mostly right code that could be ready now, without incurring all of the problems of the complete hack. When we approached the areas where this solution began to break down, we got an indication that there was a problem and could fix it when needed.

      This might even be a good tactic to help mitigate the risks in a quick-and-dirty solution.

      Imagine the following scenario.

      • The right solution will take a week
      • The quick hack will take a day, but will cost a day's effort every month to work around/clean up
      • With an extra hour or two of effort, we can think we can reduce the monthly cost to somewhere between 2-4 hours.

      It is likely the business side and technical side would see this as a worthwhile investment of extra time.

      G. Wade

        As I was writing the other comment, another strategy came to mind. Anyone with a mortgage or car loan is probably familiar with a useful piece of advice for servicing a long-term debt. Making an extra payment now and again can make a significant difference in the time to pay off a loan

        In the context of technical debt, we could imagine a commitment to spend some time now and again to adding tests or doing some refactoring to pay of some of the principal of the technical debt when we get a little time. Imagine you have a little time at the end of an iteration, adding a few unit tests or validation for edge cases to our worst offenders could reduce the cost of working with this code. As the debt is reduced, so is the interest we end up paying.

        In the case of a financial debt, this kind of extra payment strategy requires a fair amount of discipline, but it can reduce the time to pay off a debt significantly.

        It might even be possible to schedule this kind of work in a bug tracking system or as part of the task list for a project. We could consider this lower priority work that is only scheduled when we begin to catch up.

        G. Wade
      You would probably think of developing a method of measuring technical debt (rather than a simple equation or model) because it must necessarily be project-specific, and the "true cost" of each item (ex. deferred refactoring) is best known by those that would implement them.
      Really? I find that a dubious statement, and I'm not going to accept it if you don't add some substance to the statement.

      "True cost" of each item not only depends on how often bugs need to be fixed, but also on how many additional features need to be implemented - and that's likely to be a more significant cost. After all, technical debts often comes from taking short-cuts - which lead to less code. Less code leads to fewer bugs, and easier fixes. But it makes it harder to expand the system. However, it's usually not the developer who decides if and how many features will be added. It's the customer (internally or externally).

      And this brings up another point. Debt in the financial world is often a well understood quantity. A mortgage lasts 20 or 30 years. Loans between banks will have a known interest rate, and it's known when it will be repaid. Not so with software. I may have some idea how much "technical dept" a project creates, but often it's not clear at all how long it will last. A piece of software may be obsolete within a year. It may last 20 years. And even if it lasts 20 years, there may not be demand for change.

      Quantifying debt (and its risks) means you have to have a good idea of the future. Financial institutions do that with contracts and collaterals. But that doesn't translate to software.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://797313]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (9)
As of 2014-11-21 19:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My preferred Perl binaries come from:














    Results (114 votes), past polls