
Technical Debt - BerislavLopac
https://martinfowler.com/bliki/TechnicalDebt.html
======
ljm
My only bone of contention is that taking on debt is usually a conscious
choice. Technical debt to my mind is the price of making a pragmatic decision,
it’s the trade-off that lingers.

Making poor architectural decisions or writing poor quality code isn’t tech
debt. They are just institutionalised consequences. The way the world now
works.

Legacy code isn’t tech debt either: it was right for the time.

What you have instead is knowledge debt as engineers turn over, and the once
intuitive and elegant parts of the codebase are utterly alien to the new hires
who learned their craft in a totally different way. This isn’t tech debt
because engineers can’t intuitively anticipate the business’s future hiring
decisions, particularly when those are made independently of the team.

If you want to establish tech debt you have to define the schedule to pay it
off and there should be some record of that work somewhere, with
accountability attached. It is not merely the accumulation of things you don’t
like the look of or find hard to work with.

Similarly, I think MVP is a conscious choice to incur product debt because it
is far too risky and irresponsible to go all-in with your perfect vision right
off the bat. You want your initial buy in and a chance to bail out or pivot
before all is lost.

Edit: as an example that comes to mind, a bank running on COBOL doesn’t have
tech debt unless their COBOL engineers are aware of their missed
opportunities. If they think COBOL is no longer fit for purpose, it’s not
debt, it’s time to reinvest.

~~~
coding123
I think of all the code written as technical debt. As soon as you write it, it
becomes a burden - just like regular financial debt. However instead of
thinking of code like a credit card loan that will take a few years to pay
off, think of it like a mortgage that you have for 30 years. At the 30 year
mark, you will generally have retired the code, hopefully. If you're not so
lucky, you should expect to see balloon payments coming shortly. I know this
isn't a perfect metaphor because honestly "technical debt" applies to all
code, not just slightly bad code. That's very different from a loan.

~~~
Jedd
I suggest that all code is a _liability_ , rather than a debt per se.

This assumes all things can be usefully viewed through the prism and language
of economics (though my gut feel is few things can or should be).

~~~
aaronchall
Liabilities _are_ debts.

> liability: a thing for which someone is responsible, especially a debt or
> financial obligation.

According to the balance sheet equation,

> Assets = Liabilities + Owners Equity

Certainly all code _is_ a liability - it must be at least understood and
maintained from time to time (80% of lifetime cost is in the maintenance).

And while an accountant might also mark it an asset - not all code is an asset
- and we recognize that fact when we delete for badness or disuse - or rewrite
it to make extending and maintaining it easier.

~~~
Jedd
As intimated, I'm not sure that the fuzzy language and world of economics is
the best way to view such things, however ...

I'd accept that debts are a subset of liabilities, but not that 'liabilities
are debts'.

A debt implies an externality, while a liability implies some generic exposure
-- it's that which I focus on when considering (all) code as a risk to an
organisation.

I suspect, however, that we agree on the fundamentals. There's some cost and
risk to developing and trying to maintain any code base, and accepting that
can usefully inform development and operations work better than thinking of
code as a (near-)risk-free asset.

------
rsweeney21
I cut my teeth as a developer on the Windows operating system. Because we were
a platform, we had learned that when we shipped an API it became more or less
permanent. So technical debt was a huge part of our planning and thought
process.

When I joined Netflix I was assigned to add DASH support to the Silverlight
web player. I spent weeks working on the new architecture, refactoring the
streaming code, etc. One day my manager stopped by my desk and said that "I
needed to wrap it up. It was taking too long." I was still weeks away from
being done. I explained to that I was cleaning up a ton of technical debt and
that's why it was taking so long.

He explained to me that they had different values on his team.

1\. Most code will be rewritten every 2 to 3 years. 2\. For code that doesn't
get rewritten often, preserving battle tested code trumps paying down
technical debt

Just remember that technical debt doesn't apply to all software.

~~~
varjag
> 1\. Most code will be rewritten every 2 to 3 years.

a.k.a. defaulting on the technical debt

~~~
thaumaturgy
No, this is still a payment against technical debt. From the top of Martin
Fowler's article:

"The extra effort that it takes to add new features is the interest paid on
the debt."

If adding a new feature starts with, "just throw out all the code and start
from scratch", that's a much larger cost over the long term than building code
that's easier to maintain and refresh.

~~~
sidlls
With very few exceptions code that is "easy to maintain and refresh" over any
appreciable time horizon (say,longer than 2-3 years) requires the kind of
engineering effort that the modern world of "CS trivia is good interview
material" generally derides. I'm not even talking about "real" engineering
processes as might be used for space systems or whatever; I mean just basic
requirements analysis and technical documentation.

------
kashyapc
[I recall posting this here in the past, but worth re-posting.]

The "handy rule" from the book _Team Geek_ \-- the newer edition is called
_Debugging Teams_ [1]. It's from chapter "Offensive versus Defensive work":

 _[...] After this bad experience, Ben began to categorize all work as either
“offensive” or “defensive.” Offensive work is typically effort toward new
user-visible features—shiny things that are easy to show outsiders and get
them excited about, or things that noticeably advance the sexiness of a
product (e.g., improved UI, speed, or interoperability). Defensive work is
effort aimed at the long-term health of a product (e.g., code refactoring,
feature rewrites, schema changes, data migra- tion, or improved emergency
monitoring). Defensive activities make the product more maintainable, stable,
and reliable. And yet, despite the fact that they’re absolutely critical, you
get no political credit for doing them. If you spend all your time on them,
people perceive your product as holding still. And to make wordplay on an old
maxim: “Perception is nine-tenths of the law.”_

 _We now have a handy rule we live by: a team should never spend more than
one-third to one-half of its time and energy on defensive work, no matter how
much technical debt there is. Any more time spent is a recipe for political
suicide._

[1]
[http://shop.oreilly.com/product/0636920042372.do](http://shop.oreilly.com/product/0636920042372.do)

~~~
ben_jones
I think that's a leaky abstraction. Code refactoring can have a huge
performance impact that is 100% noticed by the end user.

~~~
tj-teej
I think the OPs paradigm holds. If the Code Refactoring has a huge performance
impact then it's Offensive work, if it has no impact, then it's defensive.

~~~
brightball
IMO you just pointed out the key to selling the work.

Reclassification.

~~~
hinkley
It’s dirty accounting tricks for a greater good. I kinda resent the fact that
we have to resort to this.

~~~
brlewis
A huge performance impact is a shiny thing that is easy to show outsiders and
get them excited about. There is no dirty accounting here.

~~~
jolfdb
The dirty accounting is that doing work to prevent bugs gets no credit, but
letting bugs happen and then fixing them gets credit.

~~~
wolf550e
Even worse, introducing shiny features in half-baked bug ridden way gets
credit, the person who gets to fix all the bugs and possibly reimplement the
whole thing correctly gets no credit.

------
baby_wipe
I've been thinking about the difference between video game software and most
CRUD software. With most CRUD software you are expecting future changes, so
you have to be more conscious about tech debt. But with video games (at least
older ones), once you ship you're more or less done.

I wonder if that gives room to take on extreme debt at the last minute before
shipping a game. An example might be when Steve Ellis added multiplayer to
Goldeneye on N64 a couple months before launch. Since they were going to ship
a finished product, he was probably able to build it much faster without
having to worry about code quality.

[https://www.engadget.com/2012/08/14/goldeneye-007s-multiplay...](https://www.engadget.com/2012/08/14/goldeneye-007s-multiplayer-
was-added-last-minute-unknown-to-ra/)

~~~
steveklabnik
One thing that's interesting about this insight is that many games are moving
_away_ from this model, with regular updates and continued development. This
doesn't invalidate your point, of course, but I also wonder how big of a
mental shift this must be, because historically, when a game was done, it was
done.

~~~
aarongray
That's a great point. One of my favorite games, Enter the Gungeon, had plans
for a major release of DLC, but they canned it and replaced it with a much
smaller scope of free updates because they had so much technical debt that
they couldn't attempt the big DLC release confidently.

[https://www.reddit.com/r/EnterTheGungeon/comments/9ykpgc/onc...](https://www.reddit.com/r/EnterTheGungeon/comments/9ykpgc/once_more_into_the_breach_an_update_on_gungeon/)

~~~
steveklabnik
Ah, thanks for that! I love that game too, and forgot about this, it’s a great
example.

~~~
aarongray
Ah nice! :)

------
rossdavidh
I like the metaphor of technical debt, but...this essay does not address the
most prevalent obstacle with paying down technical debt, which is that the
people making the decisions don't care. They are in short-term mode, just
trying to get this year's objectives met and IPO or sell or get a higher up
job in a different company or division. They really don't care about the long-
term health of this software product. Technical debt, as a metaphor, may make
perfect sense to them, but they aren't the one who will pay the interest.

Now, if you're working on open source and will be in this codebase for a
decade, or this is your company or your software, it makes the tradeoffs much
clearer, and that works because your incentives are right. So this metaphor
works better for helping the typical developer make choices well, than for
helping the typical manager/director/CEO make choices well.

~~~
foolfoolz
this is usually a communication problem from engineering. you have to be able
to describe the impact of the risk and benefits and make a business case for
it. no one cares if you want to upgrade a framework. but if you are going to
improve customer trust by using a newer version of something and result in
less bugs / downtime it sounds a lot better

~~~
rossdavidh
Sure. But the risk of disruption is usually actually higher, in the short
term, by paying off the technical debt. In the long run, of course, it will
likely result in fewer/less risk of technical problems impacting customers.
But the risk of there being a disruption right now, is nearly always higher if
we pay down technical debt, than if we put it off. So again, you have to have
something other than a short-term outlook on the part of the decision maker.

Which does happen, of course, but not always, and not almost always either.

------
jaden
One of the hardest challenges of paying off technical debt is that there's no
visible improvement to the stakeholder. From a business perspective, they
often think it's working now, why not leave it alone?

Also, the metaphor starts to fall apart if you consider good debt vs bad debt
in terms of financial investments. No examples of good technical debt come to
mind, other than the benefit of shipping quickly.

~~~
LargeWu
[https://www.youtube.com/watch?v=XakfJ2spb3w](https://www.youtube.com/watch?v=XakfJ2spb3w)

A pretty good talk from Railsconf a few years back. The debt metaphor can be
thought of as two axis: planned vs unplanned, and low vs high interest.

If you explain to the stakeholder that by not paying down technical debt,
they're only paying off the interest, but they have to keep paying it forever,
perhaps that will sink in. The opportunity cost of those interest payments is
profit-generating work. By failing to address technical debt they are
constraining the business.

~~~
james_s_tayler
I've come to adopt the metaphor of Technical Tax instead for this reason.

Technical Debt is something for which you have a repayment plan and a timeline
on which it will be repayed and you are making the repayments.

Technical Tax is everything else. And your tax rate will keep climbing higher
and higher unless you make a change at the policy level.

------
DoubleGlazing
My previous job had an excessive amount of technical debt in it's core
product. So much so that simple code changes that should have taken a few
hours were now taking days, or in some extreme cases weeks. For example there
were financial calculations that should have been confined to one class and
treated like a black box, but over time bits of the calculation had spread out
all over the application from the front end, the server layer and in to the
DB. A simple change had a ripple effect on other parts of the application
which made bug hunting and testing a slow and laborious process.

After much grumbling from the devs the CEO prepared a presentation where he
told us technical debt was our friend. We had a choice to pay down the debt,
or add new features. New feature would get us more customers, and more income,
which would mean we could hire more developers to eventually pay down the
debt. I felt it was a very wishfull thinking type of argument. We were having
increasing numbers of outages due to the lack of a proper testing process in
our CI pipeline and our DB was massively overloaded. Adding new feature was
literally adding to our technical debt and increasing our risk of outages,
something that wouldn't help get new customers.

My issue with the above argument is that the problem with debt isn't the
amount or type, but the person holding the debt. A 30-something in a safe job
(e.g. doctor) earning €100k a year can safely hold €300k of debt, so long as
they are responsible and always strive to reduce the amount owed.

A 20 year old working in a fast food joint on minimum wage, but holding €50k
of debt is in serious danger. They aren't in a stable job and they aren't
being responsible.

Some companies are like the doctor. They have debt, but are responsible and
actively work to reduce it. Some are like the 20 year old who thinks that they
can deal with it later, oblivious to the rising interest and danger they are
putting themselves in.

------
allenu
I dislike the term "technical debt" as it makes it appear that it is something
that _must_ be paid. It takes a stance that there is a correct way to do
something and that if you owe a debt it's because you've strayed from the
correct way and that you need to restructure your work to make it conform more
to this correct way.

I prefer to see engineering as a series of trade-offs. These trade-offs come
about often as not having enough information about future scenarios and yes,
sometimes they come about because you are in a rush to do something. Either
way, whether something should be redone is dependent upon a lot of factors and
calling something "technical debt" is a sort of way to politicize work as
though it is "the right thing to do" and msut be done. This feels too
simplistic to me.

Often, shortcuts we take will live for a long time in our code and often it
doesn't matter that it's "wrong". If we call something technical debt, we
should only call it that at the time that we determine work definitely needs
to be done, not as we're going along and thinking "this is not the ideal
design" as this will just lead to YAGNI designs.

~~~
WorldMaker
> I dislike the term "technical debt" as it makes it appear that it is
> something that must be paid.

You don't _have_ to pay other debts either, you just have to be prepare to
deal with consequences of that (bad credit scores, bankruptcy). Real debt too
you often have choices in what you pay off today, versus what can wait for
next month or next year.

There's also nothing inherently _wrong_ with taking on debt. Most people will
have all sorts of debt in their lifetime, and some economists believe that
debt is much more interesting economically than wealth ever is. Debt is not a
moral proposition and calling something "technical debt" isn't saying that it
is bad/wrong, it's saying that we're writing IOUs we may or may not have to
cash at some point. It isn't necessary to avoid debt at all costs because it
isn't wrong to have some debt on the books (beyond very conservative religious
readings that feel that all debt is sinful, of course).

~~~
mobjack
There is a lot of technical debt you can leave in the system without
consequence.

Tech debt mainly becomes an issue when making changes to the code. If no
changes are needed in the code and it is working correctly, it is best to
leave the debt in there.

~~~
WorldMaker
I think that gets to other people's points that if it doesn't have
consequences it is isn't likely "tech debt". If you don't "owe" it to someone,
and often that someone is "future you", then it isn't really tech debt, it was
just a trade-off or a poor aesthetic. We have other fun names for ugly
aesthetic choices that work and get the job done and aren't likely to be
replaced such as "jerry-rigged" and "Rube Goldberg machine" and "duct-taped
shambles".

------
Eleopteryx
This is painful for me as a Rails dev because the real technical debt is
always a lack of test coverage. Cleaning up cruft is great, except without
tests I'm just going to break my application in the process (and probably not
know it.) Without first defining the behavior of the application, there's a
reduced incentive to refactor anything. In this way, there's effectively two
layers to the technical debt.

This becomes a compounding problem, where the technical debt gets so great
that it becomes more appealing to just keep pushing out features and dealing
with the fallout. Everywhere I've worked, the code has ended up exactly this
yucky. And yes I've contributed to it too. I just don't think that the idea of
paying for someone to go back and make the code nicer with no tangible changes
to the application's external behavior doesn't seem to resonate with my CTOs.
Maybe I just need to find better places to work.

~~~
stank345
I have experienced the exact same thing in Python and it feels bad to not make
changes out of fear of breaking something. So much so that I won't do
refactoring on a large codebase written in a dynamic language with not great
code coverage (i.e. pretty much every one I've worked on professionally).

This is where static typing can help a _lot_ in my experience. Your types (and
your function signatures) are contracts you still need to adhere to after
you're done refactoring. Keep making changes until the compiler tells you it's
all good and then usually it is.

------
kazinator
That cruft is due to "requirements". It's easier to modify a system with less
cruft, because modifying a system means adding, deleting or changing
requirements. This is easier to do when there are fewer of them.

If you think of a new requirement, it's easier to be sure that it doesn't
conflict with six requirements than with sixty, or six hundred.

Additionally, requirements are hard to remove/change once their
implementations are deployed and depended on.

Basically we are already saddled with debt at the requirement level, before we
even consider the implementation quality.

Thus, the first tool in the fight against technical debt is to very carefully
manage the acceptance of new requirements. If a requirement doesn't exist,
then its code doesn't exist, and that's as clean and maintainable as code can
possibly be.

Secondly, try to gather all of the requirements up-front before implementing
anything, and then resist futher requirement creep. If most of the
requirements in a system were gradually introduced after implementation began,
that will tend to degrade the quality.

------
Traster
I kind of like the idea of calling it technical debt- because I can declare
technical bankruptcy (move companies). But really it doesn't work, partly
because technical debt very often is actually the result of doing a slap-dash
job in the past. If this code was unimportant enough to just throw together in
the past you really need to ask yourself whether it's important enough today
to fix. This feeds in to one of the fundamental personality types - someone
who may be more interested in making the code beautiful and streamlined and
neat than actually improving the bottom line.

There are cases where you need to consider technical debt, but most often it
should be considered as something you create rather than something you
inherit- because the creation of the technical debt is where you're making the
judgement:

* Is delivering now important

* Is this code going to need to adapt and develop in the future

* Is the code this is building upon going to stick around or will this code likely be superseded.

* (Selfish developer: Am I going to be around to deal with this)

------
Bokanovsky
I think when trying to categorise technical debt the Technical Debt Quadrant
is a better tool [0]. It's already linked to in the parent article.

A lot of people are shoving all technical debt in the Deliberate / Prudent
category. However I've seen a lot of code bases written by inexperienced
developers and it would have be done completely differently if they had any
experience (both of the inadvertent categories). This means actually updating
the code base can be a complete pain. Sometimes you know if you're editing the
code you risk creating huge regression issues and suddenly something that
should have taken a short time can spiral out control if you want to add more
functionality.

[0]
[https://martinfowler.com/bliki/TechnicalDebtQuadrant.html](https://martinfowler.com/bliki/TechnicalDebtQuadrant.html)

------
donmatito
My framework to think through technical debt: I don't think of it as debt
(negatively connoted) but business investment.

When you take a debt it's usually to finance something. Focusing the wording
on debt highlights the negative side of the trade off. It's like we're
suddenly all turned fiscal austerity hawks, where any bit of debt is evil.

I feel like developers are each placed somewhere on a continuum from purist to
entrepreneurs. Purists can spend weeks to tweak an SQL query, while
entrepreneurs would be happy with a no-code Zapier MVP that actually lands
customers

It's not to say that one is always better than the other. A balanced team
probably needs both. In our company, I'm more on the entrepreneur side (which
I guess is good for launching a startup) but the recent addition of a "purist"
to the team has improved our codebase significantly.

~~~
wccrawford
People who understand financial debt don't think of it as evil. It's a tool
they use.

Technical debt is the same way, and I often talk about it that way at work.
But it's a phrase that means something that "business investment" doesn't.
When I tell my boss that we're incurring technical debt (and what exactly that
debt is), he is already in the "business investment" mindset on the matter.
I'm the one trying to reign that in and focus on making the future easier by
avoiding some of that debt now. But I fully understand both sides of the
matter.

------
babesh
'technical debt' is a misnomer.

The reality of most code, especially as it gets closer and closer to the end
user, is that over time there will be requirements added and removed. It is
really hard to perfectly design such a system from the start.

Thus some level of technical debt is inevitable and it isn't really debt. For
instance, an overriding goal of zero technical debt is not always the right
decision. You may be expecting additional requirements and have not come up
with a better conceptual model.

This focus on the technical makes you lose sight of underlying issues which
are often organizational rather than technical. Is someone neglecting the code
intentionally to get a promotion for a rewrite? Is there a ship now or feature
mentality? Are your engineers empowered to change the code?

Other industries and systems have the same issues. What do they call this?

~~~
kraftman
You can't redefine technical debt to include future requirement changes, and
then say that definition is wrong and it isn't really debt.

~~~
babesh
It's not future requirement changes. Its that the conceptual model that you
constructed for your original requirements doesn't accommodate a new
requirement. Now if you construct a new conceptual model, you will have to
modify the original code. It sometimes isn't feasible to do this to each new
requirement especially if you suspect that the next new requirement will
require yet another change to your conceptual model.

This can happen because the product roadmap changes (new PM, business changes,
etc...)

Try writing UI for several different designers over the course of several
years for several different iterations of features when there is no common
design language.

~~~
kraftman
Technical debt is about quality of code, not about changes in your conceptual
model.

Lets say I had a warehouse that stored food, all stored neatly in its own
section, each with the least frequently moved at the top where I need a
forklift to access, and the most frequently used at the bottom where they are
easy to access.

Someone orders too many boxes of rice, and there's no room in the rice
section, but there's room on the lower shelves of the sauces so it gets stored
there, and some are left on the floor, partially blocking forklift access.

The immediate problem of rice storage is solved, but every time I need sauces
I have to grab the forklift, and it may take longer to get there and back
because the route is blocked. This will persist until I refactor the warehouse
so that there is more space to store the rice appropriately.

Now the manager decides we should be able to store refrigerated goods, and I
have no refrigerators yet. The work to refactor the shelves to make room for
the refrigerators is a conceptual change in how I use the warehouse, and not a
direct consequence of how I've previously been storing goods. It's not tech
debt.

~~~
babesh
Quality of your code can be affected because your conceptual model is muddy.
Makes it more complex, harder to understand, harder to change. Makes you
implement a requirement in two different ways.

~~~
babesh
It looks as if people have different definitions of technical debt.

------
Gpetrium
I think it is worth noting that different organizations/teams may require
differing amounts of work related to technical debt. This is often driven by
business culture, priorities, team experience, long term business goals and
many more.

From experience, a lot of people/companies have difficulties marketing
what/how/why/when technical debt should be tackled for both internal and
external stakeholders. This leads to a less than optimal structure where "new"
or "shiny" work is preferable and rewarded, as opposed to a more balanced
approach.

------
austincheney
I disagree that productivity cannot be measured. Measure productivity by the
time it takes a developer to achieve a proof of accomplishing the business
requirement through test automation. If it takes a developer 1 hour versus two
business days of 8 hours there is a 16x factor of productivity.

Tech debt are all the factors that erode productivity. This includes many
technical factors from inefficient systems design to unnecessary testing. It
also includes slowness from weak developers and developer training.

I know it puts me in an extreme minority, but I am a big fan of extreme
simplicity, which is not what it might suggest. Extreme simplicity removes
everything in a system present for the easiness of the developer so that all
that is left is only that which is necessary to accomplish a business
requirement as directly as possible. If there is less to read (including
dependencies) there is less to maintain and less to test. Simplicity is not
easy.

The confusion is that a system must achieve a certain level of easiness or it
will be rejected by some developers outright or require training at great
expense. My basic premise for making any challenging decision is to never
compromise on integrity, which includes being honest about the challenge at
hand. You can embrace that challenge directly and solve for it or you can hide
from it behind layers of easiness.

~~~
m0zg
This assumes goal complexity is measurable and you can run randomized
experiments to measure what you call "productivity". Neither of these
assumptions holds in the real world.

E.g. changing some business logic can be 10 minutes of work to implement a
hack (which will pass tests, mind you), or 2 weeks of strenuous yak shaving
for a "principled" solution. Which would you rather pick? And more
importantly, are you prepared to select for developers who favor 10 minute
hacks to principled solutions?

~~~
austincheney
You measure productivity by the time it takes to complete a task. That is both
objective and measurable.

How do you define a principled solution versus a hack? All that matters is
whether the result achieves the desired business goals without regression, and
that is what tests are for. That being said I would gladly pick the 10 minute
solution that passes all the tests.

So much of development is bullshit posturing for developers to justify their
existence with unnecessary tasks to make things easier for themselves.

~~~
m0zg
You measure productivity that way on the assembly line or other menial tasks
where it's obvious how to do things and the work isn't very complicated.
Trying to do this with creative professions is a disastrous mistake.

>> So much of development is bullshit posturing for developers to justify
their existence

That applies to any profession. Developers aren't unique in this regard.

~~~
austincheney
> You measure productivity that way on the assembly line or other menial tasks
> where it's obvious how to do things

Isn't it obvious how to do things in programming? Many developers, in my
corporate experience, occupy themselves with how to do things in code. That is
exceedingly unfortunate. How to write code should be an obvious disqualifier
before obtaining employment. Nobody would hire a lawyer, for instance, who
didn't know how to a legal argument.

Writing code should be as obvious as writing an essay, but I suspect many
developers that are hiring probably have trouble writing essays as well.

Anyways, if you had the choice between a 10 minute pizza and a 3 day pizza
with ingredients more evenly spaced apart which would you choose?

~~~
jepcommenter
Writing code is not a problem, changing it without breaking is. Taking tech
debt is not a problem, paying interest on it is.

And you will hardly hire a lawyer to work in unknown to him legal domain in
foreign country in foreigh language.

~~~
austincheney
> changing it without breaking is

That is why the software gods invented test automation.

> paying interest on it is

That is why simplicity is important, because less is more. All code is
ultimately debt as it demands some amount of maintenance. When there is less
to maintain there is ultimately less debt.

> And you will hardly hire a lawyer to work in unknown to him legal domain in
> foreign country in foreigh language.

Has that ever happened to you as a software developer? The one time I was told
to learn a new language I was allowed the time and space to learn it.

------
zmmmmm
The problem with the concept of technical debt is the implicit suggestion that
you know what is debt and what is not up front. An awful lot of debt is stuff
that people thought was needed but turned out to be totally off base and now
weighs everything down. And large piece of that - not by any means all or even
most, but a large piece - is people pre-emptively optimising the design to
satisfy precepts put about by people like Fowler himself.

------
revskill
To reduce/remove tech debt from my code, the only patterns i found helpful is:
Separation of concern: The chunks of files/codes that work or removed
together.

One typical example in real world is React Hook.

By moving boring stuff into a folder called "hooks", we centralize concerns
into its own file, so that we could manage them effectively, or we don't need
to think about it anymore.

------
glangdale
I find the phrase 'Technical Debt' to be unhelpful. If I am in financial debt
I will definitely need to pay it off unless I go through bankruptcy. Technical
'Debt' seems to operate by bad analogy: I may opt to completely wipe out the
subsystem that has accrued the debt and replace it with something else, or it
could turn out that the subsystem solves some problem that wasn't business-
critical anyhow.

I've had to restrain developers from "turd polishing" systems that were poorly
thought out to begin with. Code gardening in a subsystem that was simply the
algorithmically wrong way of doing it (that we might have had to have shipped
quickly in order to stay afloat) isn't a first class activity. The problem is
with the metaphor of technical 'debt' is that implies a balance sheet, but
many (most?) of these bills will never come due.

~~~
Forge36
That's the difficult part of being new on a project. If you aren't building
the replacement is progress being made to fix the issue. With regards to
gardening: if you're spending all your time weeding but you haven't planted
any seeds what are you growing?

~~~
glangdale
Hopefully the manager has enough sense to help a new person see the
priorities. As a manager I've definitely 'called time' on weeding. Good
analogy.

------
z3t4
Something takes 20 hours to implement, but you do a hack job in 2 hours. Next
time someone touch that code, they probably need to spend the 20 hours to re-
implement it. Technical debt can can be made less costly by using the test-
first approach, you start by writing a test that confirms what you are going
to implement works. When doing test-first, it's often fine to just do the bare
minimal work. If something needs to be added/fixed, write another test, then
do the bare minimal change, repeat. Eventually the code will be so complex a
small change will take hours, and that's when you have to pay the technical
debt, but if you have all the tests, you can make a clean re-write, and the
tests confirms that the new clean code works just like the old code.

------
rsweeney21
Businesses should probably start tracking technical debt as a liability on
their books. Maybe depreciate code as an asset like a business does with a
truck or piece of equipment. Management would probably understand the concept
better if it was represented on the financials.

------
azernik
A related concept: defaulting on technical debt.

If you know a piece of crufty code is going to be irrelevant in the near term
after some major architectural change or new feature, it isn't really worth it
to pay down the principal with minor improvements or shims.

------
throwaway_ndiuf
I think it's marginally useful to think of low vs high interest debt in terms
of technical debt. I can make assumptions that certain areas of software will
not change in the future, but that in itself becomes technical debt. Now
future features have to be designed around the idea that certain features are
off limits. Sounds extremely risky to me to try to hedge your bets on this
kind of foresight. On the other hand, I think it's extremely useful to examine
different libraries / modules as having different levels of technical debt,
but the metaphor stays intact. You just look at your software not as a single
loan, but many micro? loans.

------
40acres
Technical Debt becomes really toxic when mission critical customer facing
functionality is based on it. Just this morning we received a ticket where
cleaning up technical debt caused a major issue for the customer, when we
looked even further we realized that this customer relied heavily on the state
brought on by technical debt and that resolving this issue will require an
even more careful refactoring to ensure that the debt is cleared but the
overall functionality is unchanged.

As a workaround for the time sensitive issue we literally copied the old code
and overloaded our class so that the customer runs the old code while we
develop a robust fix.

------
tcgv
> Given this, usually the best route is to do what we usually do with
> financial debts, pay the principal off gradually. On the first feature I'll
> spend an extra couple of days to remove some of the cruft.

This should be managed carefully to prevent a lot of independent gradual
improvements that don't follow a clear architectural pattern and end up
conflicting with each other.

Furthermore, all code changes to existing modules require validation of the
affected functionalities, which are often hard to spot. Hence, I'd say that a
wide scale refactoring effort needs a clear testing plan before it's put into
practice.

------
danielecook
I think technical debt extends beyond poor quality code that prevents
additions or modifications. Having worked with a large amount of scientific
software it extends into the efficiency and robustness of software.

Frequently, efficient methods or parallelization are not used and the least
creative method is implemented to solve a scientific question. Functions are
not written in a modular way but merely for a “quick and dirty” analysis.

The end result is that you spend more time getting things to run or waiting
for them to run than if you had gone back and reworked the code to begin with.
It’s a serious drag on productivity.

------
JoeAltmaier
A startup without technical debt, is mismanaged. The financial runway is the
first consideration for survival. Spending a second on anything that doesn't
get the startup to the next phase is a second squandered.

Any exception to that?

~~~
p0nce
Any market-leading product which is known for having the worst codebase out of
all the competitors?

------
ineedasername
This article frames technical debt in terms of sub-par code, which is part of
tech debt but only a part. Legacy systems that are nearing end of life,
patches and updates that haven't been applied, all of that represents
technical debt as well. And when it comes to some of it, it can be actual
financial debt too. Plenty of legacy systems sit around a long time past their
sell-by date because of the financial cost of replacement, which may be orders
of magnitude more than the cost of maintenance.

------
ozim
Funny thing about technical debt with programming is that sometimes, and in my
experience I did not had to pay it back... Software went to trash just because
business changed direction.

------
flr03
A lot of people seems to complain about the wording. I understand the analogy
doesn't cover 100% of the issue but unless somebody finds a better one this is
the best we have. Good enough so that stakeholders do sometimes allow us to
take care of it. Yes probably not all the time, and not enough, that's why we
need to get better at communicating about it. In a corporate environment,
communications skill are as important as technical skills, and we should seek
to improve both.

------
Bombthecat
Technical debt is like real world debt.

You can either take the debt and try to increase your business revenue more
than the interest of the debt.

The same is true for the technical debt,or decision not to modernize / write
shitty solutions to fix something quickly.

In real world any business man would ask before taking the debt: is there a
chance paying it back.

But no one asks about paying technical debt back,or if ignoring it will yield
a high enough return ..

------
clumsysmurf
For anyone interested, a new book on the topic just came out

"Managing Technical Debt: Reducing Friction in Software Development (Sei
Series in Software Engineering)"

[https://www.amazon.com/Managing-Technical-Debt-
Development-E...](https://www.amazon.com/Managing-Technical-Debt-Development-
Engineering-ebook/dp/B07QRT48T6)

------
erikpukinskis
As a side note, I noticed Fowler linked the CannotMeasureProductivity page
using camel case, and that took me right back!

I remembered using PhpWiki and being able to auto-link pages just by using
camel case. I don’t believe MediaWiki has that capability. And it’s such a
standard I had forgotten it even existed.

Something very soothing about the idea that links could be handled so
gracefully.

------
branko_d
This is not just about the code, but also about the feature this code
implements.

A feature implemented through "indebted" code tends to be buggier and less
performant. There are exceptions, of course, but by-and-large this has been my
experience.

So the "interest" is not repaid by just the programmers, but also by the
users, over and over again as they use the feature.

------
afarviral
How many companies are profiting from a poorly written codebase that just
works well enough to be a parketable product and isn't being maintained and
there is no plan to maintain it? I can think of many utilities not being
actively developed that are still part of or a product in their own right.
Surely that isn't debt in any sense?

------
eddyg
It's not "technical debt", it's "escalating risk". Technical debt gives the
wrong impression to business people.

[https://twitter.com/jessitron/status/1123310331957145601](https://twitter.com/jessitron/status/1123310331957145601)

------
largolagrande
I really like the comparison of TD with the Tetris game : "You can’t win. You
can only control how quickly you lose"

Already posted on HN here :
[https://news.ycombinator.com/item?id=19353352](https://news.ycombinator.com/item?id=19353352)

------
uberdru
The concept of 'technical debt' seemed to emerge around the time that the
concept of 'scoping' went out of of fashion. The best engineers that I have
ever worked with were truly masters of scoping projects.

------
kissgyorgy
> Stated like that, this sounds like a simple matter of working the numbers

I don't think it is that simple, because the attempt to remove cruft might
introduce new one and can make it even harder to reason about the code.

~~~
bradenb
He goes on to say it isn't that simple because we're bad at estimating and
measuring productivity.

------
adamdonahue
It's only debt if you have to pay it back.

------
crimsonalucard
Technical debt is a bad name for this phenomenon. The word debt implies that
we know it exists at the time of taking on the debt and that it can be paid
back.

In reality a lot of technical debt can never be paid back without restarting
from scratch, and a lot of it is accumulated unknowingly only to be discovered
way later in the project.

~~~
sixstringtheory
I would say technical debt is only that which you already know about but have
made an intentional decision to take out a “loan” to ship quickly.

I’m having trouble thinking of an example of financial debt that can be taken
on unknowingly. Maybe identity theft? But that's less like an engineering
tradeoff... more like NSA backdoor type stuff.

~~~
crimsonalucard
Debt heavy choices made knowingly are more rare, as programmers consciously
avoid it or choose debt that won't accumulate beyond certain bounds.

Whatever it is, I think most projects deal with "technical debt" accumulated
unknowingly. There's no theory around how to create a "good design" and thus
it's often shooting in the dark or using preexisting patterns. Most software
projects have design flaws that only become evident later. In my career, I
have dealt with this type of problem more-so then debt accumulated knowingly.
Additionally my current company is calling this type of debt, technical debt.
I have rarely rarely seen technical debt taken on knowingly and documented.

~~~
helen___keller
> Debt heavy choices made knowingly are more rare, as programmers consciously
> avoid it or choose debt that won't accumulate beyond certain bounds

I don't know what kind of software you work on, but I disagree. It's
incredibly common, from what I've worked on, that we have an existing
subsystem X, and project management wants it to interact with this new
subsystem Y but it was never designed in a way to do so, so either we can hack
it in real quick, build a moderately pleasing integration with only a little
technical debt, or completely rebuild X from the ground up in a way that makes
sense and leaves no technical debt. From my experience, bad managers will want
the quick hack while engineers and good managers will take the middle option.
Nobody opts for the complete rebuild.

~~~
crimsonalucard
The design of subsystem Y is likely technical debt. The reason is, because of
agile, software developers know that they must code defensively to account for
feature changes or additions in the future. That means you take on technical
debt every time you make a subsystem that isn't modular, meaning that if
system Y is not infrastructure it should be able to be pulled out and used
somewhere else. To not account for this feature is to not account for future
change.

A good way to test if your subsystem is modular is to ask yourself, can you
pull your subsystem out of the current system and use it in a completely
different app in a completely different context? If the answer is no, then
likely the module is either IO or too tightly coupled with other systems. Too
much Mocking in your tests is another sign of a design flaw. It's a signal
that your code is dependent on other systems rather than a module that can be
pulled out and reinserted somewhere else.

Another design flaw is, is system Y itself made up of modules or
interconnected dependencies? If subsystem Y needs to reconfigured to do
something slightly different can I pull out 10% of the system and replace it
with new modules? Or does pulling out 10% of the system involve pulling out
another 80% of the system as a dependency? You wanted a banana but what you
got was a gorilla holding the banana and the entire jungle.

Most programmers choose dependencies because modules are harder. Also the
dependency style of programming is heavily promoted. Additionally, most
programmers are Unaware of what it means to make a modular component, they
organize code following nomenclature rather than a systematic theory, and they
think they are doing modular design but they are not.

Likely your subsystem Y was designed in such a way that it is tightly coupled
to another subsystem and can't be used outside of a certain context. Possibly
it is tightly coupled with IO or some specific database schema. Likely system
Y itself is made up of modules that are interdependent. Also likely it was
programmed by someone who did all of this unknowingly.

So it could be a matter of perspective. What you see as debt taken on
deliberately I see as debt from the past "discovered" and interest accrued
because the debt can't be paid back without a rebuild.

------
bubblewrap
I always thought "technical debt" was just a buzzword consultants use to make
the client pay more money upfront. To me it translates to simply "work we
haven't done yet".

