Posted by Uncle Bob
The term Technical Debt
was created by Ward Cunningham to describe the engineering trade-off’s
that software developers and business stakeholders must often make in
order to meet schedules and customer expectations. In short, you may
need to use suboptimal designs in the short term, because the schedule
does not allow longer term designs to be used. As a simple example,
your initial website design may need to be frames based because you
don’t have time to build an Ajax framework.
Clearly this causes a debt. If the customer is looking for a web
2.0 system, then frames just aren’t going to cut it for long. So time
is going to have to be carved out of a future schedule to refit the
system with an Ajax solution.
In short, the business has decided that it can afford to delay release 2 in order to accelerate release 1. Is this wise?
Businesses make this kind of trade-off all the
time; and there’s nothing inherently unwise about it. If the early
release of 1.0 drives the business that pays for the development of 2.0
then the business has won. So this kind of reasoned technical debt may indeed be appropriate.
Unfortunately there is another situation that is sometimes called
“technical debt” but that is neither reasoned nor wise. A mess.
Technical debt may be necessary, but it had also better be clean! If you are going to implement a frames solution instead of an AJAX
solution, then make sure that the workmanship of the frames solution is
top-notch. Make sure the design is well balanced, and the code is
clean. If you make a mess while implementing that frames solution,
you’ll never be able to replace it with an AJAX framework. The mess will impede your progress forever.
A mess is not a technical debt. A mess is just a mess. Technical
debt decisions are made based on real project constraints. They are
risky, but they can be beneficial. The decision to make a mess is never
rational, is always based on laziness and unprofessionalism, and has no
chance of paying of in the future. A mess is always a loss.
When you buy a house and take on a big mortgage debt, you tighten up
all your spending and accounting. You clean up your books and your
budgets. You behave with increased discipline. The same is
true of technical debt. The more technical debt you take on, the
tighter your disciplines need to be. You should do more testing, and more pairing and more refactoring. Technical debt is not a license to make a mess. Technical debt creates the need for even greater cleanliness.
When you decide to take on a technical debt, you had better make
sure that your code stays squeaky clean. Keeping the system clean is
the only way you will pay down that debt.
Leave a response
Torbjörn Gyllebring 25 minutes later:
Excellent, just marvelously put. Now how do we get people to actually act on it?
Great post. But I do think the metaphor of debt still works with messes. A mess is debt that has spiralled out of control, acruing interest faster than you can pay it off.
Which raises an interesting question about declaring bankruptcy on legacy code. Some legacy code is in such a mess that in the next version of the product it will simply be binned and rewritten. When fixing bugs on legacy code that is approaching end of life, maybe there is a case for shrugging your shoulders, and adding to the debt, rather than fighting a losing battle.
I’m not trying to be cynical. In fact, I’m in the middle of performing open heart surgery (refactoring with nowhere near enough unit tests) on a very large legacy codebase at the moment. I’d love to believe we’ve not yet reached the tipping point, and there is a chance of cleaning up the mess and paying off the debt.
Bram Bruneel 38 minutes later:
I agree. However, using the term ‘technical debt’ for messy code might give you more diplomatic leverage towards management and fellow coders who created the mess. But then again you are just fooling everyone …
Kevin Baribeau about 1 hour later: Jon Dalberg about 1 hour later:
I used “technical debt” to describe all kinds of horrible code – thanks for pointing out the difference! Now I know better…
Gerard Mendes about 1 hour later:
I’m not sure I agree entirely. I think that there is always a trade-off : the better your design, the lower your interest rate. If you make a mess rather than an elegant-yet-suboptimal solution, the cost will be higher, but might not be a net loss.
Now don’t get me wrong : I’m not advocating bad design, quite the contrary actually. When you borrow money, you should aim for a low interest rate, but if you need a lot of cash, you may have little choice. Of course, the real problem is recognizing how much you need and make the optimal trade-off (because making a mess when you had the time to devise a sustainable solution is a terribly bad trade-off).
However, I do agree with Uncle Bob on the bookkeeping aspect : you should always know exactly how deep you are in debt, otherwise your so-called investment will be a burning hole in your project.
If you keep on accumulating technical debt over time- without repaying it, – it will then snowball into “Moral debt” AKA mess.
In an Agile shop, we give the project owner only what he asks for and nothing more unless there is an obvious reason. Choosing to use frames to implement functionality because the product owner hasn’t yet specified (in the current iteration) that the frames are unacceptable is not “debt”, it’s agile. It’s satisfying the immediate need of the product owner as has been agreed to by the team and product owner.
When a backlog item is pulled into an iteration that specifies the need to remove scroll bars and implement a page that dynamically redraws it’s elements, then that specification is met using AJAX.
Instead, technical debt is debt internal to the product. I’ve most often heard this term used with reference to hard to test code or code that is not really “object oriented”. This is, in my opinion, the definition of a mess.
Sorry to disagree with you Uncle Bob, but a mess is technical debt. Choice to use frames during an iteration is just planning the iteration.
Jason Y about 4 hours later:
Can we clearly define mess and debt? If we cannot agree on definitions, we cannot arrive at any conclusion on the truthfulness of the original proposition.
Jim M about 4 hours later:
I see this sort of delusion most frequently in so-called “lean startups” that are using a web framework to get the project off the ground but do not recognize that critical inflection point when they need to isolate the framework from the rest of the project and establish firm apis and abstraction boundaries. You know a project has reached this point when some part of the system (usually a computationally expensive, long-running task) needs to wander off into its own process space, but all of the existing code that would make this task easier is too tightly tied to the framework so a decision is made as to whether the effort should be spent fixing things or if you can just get by with a few bits of monkey-patching “just for this one case.” The latter gets the iteration done faster so to some it appears to be the logical choice. Repeat this a few times and eventually the weight of the mess begins to drag everything else down with it.
Thanks! I have had this feeling that the term technical dept is thrown around all too loosely. And that it might sometimes fool business into thinking they are in control. This was for me a very well needed read. Thanks again!
I pretty much completely disagree with this. A clean, well-maintained codebase that uses old tech (your frames analogy) isn’t technical debt, but a big mess is.
Cleaning up that old code is “paying off” the debt, lots of effort for no tangible results in the product. Moving to a newer technology is new development (the ajaxy web page will have a better user experience than the framsey one).
In the original paper, a distinction is made between “good” debt (doing something suboptimally in order to get a short term benefit) and “bad” debt (plain old sloppy work, no upside), and it seems like that distinction is what you’re trying to reinvent here.
Bjørn Konestabo about 5 hours later:
I know technical debt when I see it. I can feel it in my bones. It’s the thing that slows writing new things to a crawl. The stuff that keeps breaking when things are added. It is the insanity that forces you to jump through hoops for the smallest increment in functionality. It’s also why the build time is so high.
While both messy and non messy code can be indebted, code that is part of technical debt is often messy, because the constraint that creates technical debt and messy code is the same: Time.
The metaphor of debt is apt because technical debt incurs a technical cost. It is a burden that increases as the debt increases.
Making a mess when you have technical debt makes more technical debt, not less. Like a mortage it is something you have to pay off. Just paying the interests is unwise as new debt may still accumulate.
Iain Charlton about 6 hours later:
Technical debt is a term often used when people really mean the messy code you speak of. It almost never pays off and brings down entire code bases so they have to be rebuilt. Doesn’t that makes it sub-prime?
I disagree. “Temporary designs” (“debt” according to the above) and messes gives you exactly the same characteristics: they cost in interest while you have them, and in down-payments to get rid of them. For that reason they’re both technical debts, period.
However, it is still interesting to talk about the difference, because the debt as it is described in this article is an investment to build something up, whereas a mess is like a loan to finance consumption of drugs; it will destroy both you and your economy if you don’t stop NOW.
I’m not sure to agree with the fact that a mess isn’t a debt. A debt to me is something that is going to slow us down in the future. A quick shortcut that we will need to pay back. A fix that will rott with time and come back to bite us in the ass right when we are in the rush of a release. (of course you all experienced that, don’t lie to yourself :) ). However, I find this concept of clean dept interesting. That will make debate tomorow at the office :)
Malapine about 9 hours later:
It’s easy (and often correct) to blame a mess on laziness; but they also occur when people try to accomplish something without adequate resources. This usually forces them to work /harder/ to get much poorer results. Unfortunately, the only fix is to not attempt the project in the first place…
Example: Homer’s patio table has a broken leg, but he doesn’t have the equipment or skill to weld aluminum (or the money for a brand new one). This results in a messy fix involving duct tape and a length of PVC pipe, that has to be re-done every time it rains.
Steve Py about 11 hours later:
A mess is a mess, regardless of the technology used. A mess of Ajax is no better than a mess of Frames, it’s just a newer-tech mess.
Technical Debt reflects any decision where you have justified deviating from doing the “right” thing.
When a proposed solution fails to meet a client’s initial requirements due to time or cost restrictions is not technical debt. Accepting a compromise in technology to keep costs in check, that is their decision to make. I don’t consider this to be technical debt if they choose to adapt their requirements. They can either accept it, or find someone else who claims to give them what they want for the price they’re willing to pay. (Buyer beware)
If a developer chooses to ignore requirements or shoe-horn any technology in place of a more suitable one, that’s poor design, and a mess, regardless of the “quality” of the code produced. IMO “consultancies” are masters of this. Pounding their square pegs into the various shaped holes of their clientel. New technology or otherwise.
Philip Schwarz about 11 hours later:
Warning: this comment is pedantic in nature
A stimulating post, as usual, but I am a bit worried that the term technical debt is undergoing what Martin Fowler calls Semantic Diffusion.
In a way, your post suggests that your definition of Technical Debt is different from that of Ward Cunningham. I say this because:
1) You point readers to Martin Fowler’s definition of Technical Debt, according to which, we take on technical debt when we choose a design that is quicker to put in place, but will result in a system that is harder to modify. He calls this design quick and dirty.
2) But this definition is different from Ward’s, which as he clarified recently inWard Explains Debt Metaphor, is that we take on debt when we write code to reflect our current understanding of a problem even if that understanding is partial.
But on the other hand, when you say that ‘A mess is not a technical debt. A mess is just a mess’ and that ‘When you decide to take on a technical debt, you had better make sure that your code stays squeaky clean’, you seem to disagree with Martin fowler that a quick and dirty design is a technical debt, and you seem to agree with Ward, (again, in Ward Explains Debt Metaphor) that ‘a lot of bloggers have explained the debt metaphor and confused it …with the idea that you could write code poorly with the intention of doing a good job later and thinking that that was the primary source of debt’.
To confuse things further, while in Fowler’s definition of Technical Debt, the design is suboptimal because of poor internal quality (the fact that it is harder to maintain is not visible to the end-user), in your example of technical debt, the design is suboptimal in terms of external quality ( visible to the end-user – e.g. no AJAXy auto-completion of fields as you type) but NOT in terms of internal quality (the suboptimal design MUST be clean to qualify as technical debt, otherwise it is just a mess).
We often speak of design debt as a “balloon loan”. The extra maintenance burden your short-term point solution costs are akin to making “interest-only payments”. They keep things going, but don’t pay down the principal. The cost of finally refactoring the design to a more sustainable solution is the balloon payment.
I suspect the difference between a “debt” and a “mess” may be whether your stakeholders are truly committed to paying off the loan they’re signing. If they’re committed to making that future payment, then they’ve accepted a “debt”, and your 1st phase is built so that it can be replaced in phase 2.
If they’re so focused on the short term that they will sign away the farm to get it into production without regard for the future balloon payment, then you may be establishing a system that will continue to be a “mess” for a long time.
Whether you build things for the short run or the long haul, the guiding principle should be to NEVER release a system that is not sustainable from the start. The future is tough to predict, and you may have to sustain it for years.
David about 12 hours later:
So a mess is not “Technical Debt” it’s just “Debt”?
Fowler’s definition of Technical Debt is representative of the license taken with Ward’s original metaphor.
Technical Debt as originally defined is acceptable and can be a good business decision.
People have expended the definition to conveniently include messy code. And the inference (and, I fear, the consensus) is that if Technical Debt is acceptable and can be a good business decision, then messy code is therefor acceptable and a good business decision.
Messy code happens. It surely can’t be your fault; the business pushed you too hard, the other developers are too green, Sister Mary Standards wasn’t there to smack your knuckles with a ruler. Not matter the reason, messy code is very dangerous – even a little of it. Pretending it is ok does not make it so.
“When you buy a house and take on a big mortgage debt, you tighten up all your spending and accounting. You clean up your books and your budgets. You behave with increased discipline.”
This isn’t how things have been done for the last decade or so. People have been taking “Option ARMs” where they don’t even have to make a full principal payment. The amount owed goes up and up, but the monthly payments stay low—for a while.
Eventually the mortgage resets and the monthly payment skyrockets. You end up owing more on your house than it’s worth. At this point, a lot of people are walking away from their houses and starting over.
So it seems like the “debt” metaphor continues to work. At some point you end up with a debt mess. Kind of like world economy today.
I usually use the term to describe the result of developers (more or less conscious) decisions to deliver features that are not really done. When a team is delivering features lacking automated tests, proper refactoring, documentation, or whatever is (or should be) incorporated in their Definition of Done, a debt occurs, because these features though formally delivered still require more work. Perhaps they are hoping that there soon will be more time to go back and actually finish them, something less likely to happen as the code gets messier, or perhaps it is unintentionally by lack of required skills. Either way, the debt is in their code and is collecting interest until dealt with.
If the term Techical Debt is being reserved for decisions to design systems using last year’s 1.0 technology instead of a brand new 2.0(RC1) solution, then I need a new name for that other kind of debt. Creative phrases like Deficit Programming or Ignorance Tax comes to mind, but they have a quite elitist and harsh ring to them, and seem less useful as metaphors when discussing causes and consequences of messy code with managers.
Fernando Zamora about 17 hours later:
I can see the difference between what you call a mess and debt. However, you will pay for future enhancements or extensions through the nose when you have a “mess”. Changes will not only take longer but will have side effects, taking even more time and effort(resulting in not only cost of technical currency but also cost of real currenty). In the end, even simple changes or extensions will become un-manageable (bankrupt).
The way I see it, the difference from what you are describing is that one is calculated debt and the other is uncalculated debt. The latter should not be blamed on only laziness and unprofessionalism but also on deadline pressure and the lack of experience. You can have a group of hardworking but inexperienced developers and create a bigger mess than you can imagine.
Viktor G about 17 hours later:
Great reading, this surely will stop me from using this term in an incorrect manner…
“A mess is always result of laziness and unprofessionalism” – excellent quote uncle bob.
Stephen about 21 hours later:
Completely disagree with the examples in the article. Technical debt describes implementation details only – the problem being that after a feature is built using “messy” code, it’s then hard to convince management to devote resources to clean up the code afterwards, as there is no immediate business value to paying off the debt.
Dagfinn about 21 hours later:
Whilst Ward has clearly defined what he meant by technical debt, I do believe the term is very valuable and easily communicated with the business also with regards to what you refer to as “mess” (poor professional quality on delivery).
I think technical debt should be the overarching term to describe the consequence of both consicious and unconscious decisions (ie. “mess”) that cause a debt that will have to be repaid with interest in the future.
We would then have two sub-terms:
1. “conscious technical debt” to describe debt that is a natural trade-off done together with the business.
2. “negligent/sloppy/inattentive technical debt” where a debt occurs because of poor professional skills among the implementation team.
Frank Silbermann 1 day later:
Perhaps we should refer to a code mess as being maxed out on our credit cards and barely able to make the monthly minimum payment.
I’m not sure I agree with the distinction entirely. I agree that technical debt taken on as a conscious trade-off is different than coding-like-hell or just having bad developers do sloppy work (which hiring bad developers or allowing sloppy work could be conscious as well). At the extremes the distinction might be clear but the lines blur between what’s a conscious design trade-off and whats a mess in practice.
Ultimately you end up in the similiar place, you’re paying interest on cumulative prior decisions.
I like the use of the term “technical debt.”
Distinguishing between a technical debt and a mess is important because, more often than not, software development teams decide to re-visit a section at a later time and expect to fix an isolated part of the system. However, that isolated part might have dependent parts that would magnify the effort needed for the change.
A mess is definitely not a technical debt.
A mess does have value. It can provide a “proof of concept”—and to be honest that’s where technical debt usually becomes insurmountable.
YEUNIAA (you ended up needing it after all), and now your clean prototype is just as much trash as a messy one would have been. Sometimes it’s better to start from scratch. Ask Joel Spolsky about Mozilla now.
Of course you hope you won’t architect yourself into a corner, and more often than not, YAGNI does apply. you shouldn’t use cynicism as an excuse for sloppy code.
David about 12 hours later: So a mess is not “Technical Debt” it’s just “Debt”?
Yes that’s what I would understand from this post too, ironically. Anyway, “technical debt” is just a metaphor employed in different ways by different people. As long as the 2 party of the discussion understand eachother, why would that be a problem? Ward Cunningham and Martin Fowler have 2 different interpretations, Uncle bob seems to present his own here, and we may have our own too, within our team. I don’t see the issue as long as we agree within our team / organization on what it means, I think that’s ok.
I agree with Ron. The link you provided seems to agree with Ron. A mess is technical debt. And technical debt is a mess.
I also include in my usage of technical debt when people do not upgrade or enhance their skillsets. The phrase “One years experience 20 times” comes to mind. Of course this usually causes other types of technical debt.
@Rickard – funny terms!
Maybe we can use “Technical Interest” and Bob will be happy.
Also in my experience “business stakeholders” don’t understand technology, let alone “engineering trade-off’s”, let alone asking them for their direct input.
... on technology matters. (Forgot that)
Daniel Fernandes 1 day later:
Both mess and technical debt are various levels of waste that, for instance, a team may feel the need to put up with due to external pressures. In my opinion, there is not much difference between them apart maybe from Bob’s definition of what a technical debt is that the decision to reverse the situation shouldn’t involve a full redesign. A mess is usually the kind of technical debt that is non knowingly generated by the team mostly down to inexperience.
Philip Schwarz 2 days later:
Totally agree that accruing debt should lead to more discipline, not less. However, I think debt is abused in both technical and financial manners (e.g. global financial crisis).
I wrote previously on the Shortcomings of the Technical Debt Metaphor
It seems to me that this was exactly was Cunningham was trying to say. Failing to refactor code will ultimately make the code unmaintainable.
While is is pretty easy and tempting to go back and forth and argue as to what does or does not constitute a ‘technical debt’ based on how it came about, I think it might be helpful to look at things slightly differently and not get so hung up on the intentions when you took out the loan etc.
I think maybe what is required here is to apply ‘duck typing’ and consider the prime ‘quack’ which when one hears it allows us to say, ‘yep, that’s debt’ , and the walk that when one see’s it does the same. I think that goes back to what WC was trying to get across to his boss when he first used the analogy, namely ‘it costs you interest’ until you pay back the principle’. It’s the stuff that Bjorn singles out when he talks about feeling it in his bones.
If it’s something that’s costing you interest, slowing you down till you take the time to pay it off AND if it’s something you CAN pay off somehow (by cleaning up the code, refactoring, adding unit tests, what-ever-it-takes) then it’s technical debt.
I don’t think it matters much how or why it occured (in terms of being able to call it technical debt) as long as it meets the criteria of costing you interest, and being something that could be paid off. Knowing the How and Why are good for looking back and figuring out ‘how do we avoid doing that next time’ for sure, but I don’t think they matter much in terms of identifying something as debt or non-debt.
Once this kind of debt is ‘on the books’ so to speak, the only thing that remains is to look at the cost of the interest (how much and how often it slows you down) vs the cost to pay off the principle, and decide when it makes the most sense to pay off the debt. If something is cheap enough interest wise, and costly to pay off, it might well make sense to live with it for a good while, annoying as that might be. (although I doubt that comes about very often)
Dave Schinkel 16 days later:
It depends on what you mean by “Technical Debt”. You are attempting to say here that it’s a business decision.
“Technical Debt” by most developers mean Code & Run and your pile gets larger and larger causing all sorts of debt:
- Wasted time for the developer and the business because developers have to sift through a pile of shitty code - Bad decisions made by forced unreasonable deadlines made foolishly by the business without proper scoping (Agile or not)
You say you can have fast and very high quality but that’s not necessarily reality. If you force fast 100% of the time, you will get 50% pile of shit guaranteed unless you have a team of programmers who have programmed for 10+ years and are the top of the crop and who do practice clean code.
Otherwise extra fast and top notch code …they don’t exist. You end up sacrificing one vs. the other.
Balance is what businesses need to focus on and that means iterations and SOME time to allow developers to focus on trying to produce a fair amount of clean code, not slop.
Not just fast, fast, fast especially if you’re working in a shop where the business doesn’t even prioritize anything and I mean that literally. They are a fly by night let me pick what “sounds” good and do it and shove what I did yesterday aside type of deal. If you’re working in those types of shops, fast turns into a nightmare of unmanageable applications in the long run.
Oh my god, THANK YOU!
I have always hated the term Technical Debt because I think people use it as an excuse to make a mess. The example you give here of frames vs. ajax, however, makes perfect sense. That it is a decision that the business should be able to make, and that we as programmers should have the flexibility to provide in a manner that – like you say, is NOT a mess, that allows us to enhance it in the future.
I think this type of debt (and being able to give that decision to the business) is part of being professional, not just, well… hacking :)
This is simple.
Debt is something you owe and must pay off. If it is a mess, but works and doesn’t need changed nor paid off, then it isn’t technical debt. If it prevents future development, slows or retards extensibility or other additional needs, or outright prevents changes then something needs paid down – it is then obviously technical debt.
I don’t know, making the correlation seems simple enough. It really is all about communication, as long as people get what you are talking about and take the appropriate actions based on that, does it really matter?
Mohammad Azam 22 days later:
Actually, I disagree! In my opinion a coding mess is also a kind of technical debt since it is only a matter of time that you will go back to that code and try to understand and add a new feature to it. If the code is messy then it will take you more time to make the change. The more time it takes to make the change the more technical debt you are in.
Philip Schwarz 22 days later:
For fresh insight on the Technical Debt metaphor see Martin Fowler’s latest bliki entry: TechnicalDebtQuadrant
I think Chuck vdL nailed it. A mess is technical debt. You’ve chosen a short-term win, and have a long-term price to pay. Whether that’s sticking with a current outdated design, putting functionality without testing, modifying by adding numerous special cases rather than refactoring, whatever.
A mess would only not be debt if it would take the same amount of time/resources to produce either good code or bad code, and you knowingly chose bad code. That seems rather unlikely.
I think trying to divide these different use cases up only weakens the metaphor, which would be sad, as I think it is a very useful one.
I will admit that often project are unaware that they are taking out loans—that’s a completely different issue though.