
The Way We Look at Technical Debt Is Wrong - pragides
http://bigeng.io/post/118399425343/why-the-way-we-look-at-technical-debt-is-wrong
======
dccoolgai
From years of experience, I detect in the tone of this piece a certain notion
that product managers / non-technical people tend to form when working with
developers - namely, that developers _don 't_ care about speed-to-market and
would rather agonize and winge over perfect architecture and coding
standards... What I think you'll find, more often than not, on the business
end of this attitude is a developer(s) patiently trying to explain that speed-
to-market _is_ , in fact, directly related to the technical debt accrued on
the project for all but the most static and inconsequential things. We must
think and communicate about technical debt precisely the way we do to keep
errant PMs from drifting off into the Ice Cream Sea of Candyland where all of
the half-thought-through ideas they demand be implemented immediately by
cutting all corners have no impact on the _next_ set of half-thought-through
ideas they want implemented.

~~~
moron4hire
New PMs are like children, they tend to only learn the fire is hot by actually
getting burnt.

Instead of digging my heels in on not giving such PMs everything they want, I
try to offer alternatives and put the choice on them: they can have this
feature today and in 6 months we grind to a halt because we can't fit in
anything new, or we slow down just half a beat and do it right the first time.
"Up to you, buddy," I say.

It happens with jr. devs, too. They want to use a singleton to solve a
problem, or they want to forgo using any sort of referential constraints in
their schemas.

Of course, the PMs and jr. devs always choose the shortcuts. I help them both
pick up the pieces afterwards, but I never work overtime for it. The point is
to make it clear that nobody other than themselves is responsible for their
own mistakes. They led us into the mess, they can lead us out.

After that, everyone seems to get along a lot better and everyone seems super
keen on having discussions about the "right" way to do things and how to fit
things into the current state of the project correctly.

~~~
dccoolgai
|| they can have this feature today and in 6 months we grind to a halt

Buy some daisies and chocolate for the PMs you work with... because here's how
that would go over with the ones I've had:

PM: "Yes! Cut all corners and get it done today!" ...6 Months go by... PM: "I
came up with a new idea for that! Today, please!" DEV: "But remember..."
PM:"Today, thanks!"

~~~
moron4hire
You do a job. There is a reason you are there, and it's not to write code.
It's to fulfill requests. Feel free to provide advice on how best to fulfill
those requests, provide feedback, ask for clarification, etc. But at the end
of the day, all you do is what you are told. It's not to anticipate what they
will want in 6 months, because you'll be wrong just as often as right and
you'll be in the same scenario. Just do your job.

So when you're told to cut corners today, then in 6 months you can't make
magic happen to grant their every whim, you have to let it blow up. They want
to be the leader. They are responsible for the failings of the team.

You have to play chicken with them. Because every time you capitulate, all
they know is "I got what I wanted". They don't care how much you complained or
how many hours off the clock you worked. And honestly, if you tell them it
can't be done overnight, and then you do it overnight, you're a liar and they
won't trust your judgement ever again. When you say, "can't do it", you _have_
to _not_ do it. Don't make magic happen.

Or just don't work at such places. I have thankfully been out of that bullshit
for three years running now.

~~~
omouse
That's the everyday struggle; as developers we can produce so much wealth just
by typing at a keyboard. Yet we let ourselves be controlled by people who
don't know what's what and can't even prove their ideas have any return on
investment.

As you say, _don 't make magic happen_. It doesn't matter how cool it would be
if, or how you think you'll show them your ideas are better; when you say "it
cannot be done" don't go and try and do it. Don't let the manager bully you
and don't let them try and get another developer to tackle the impossible.

I've had that happen to me where I said it will take X amount of time to do it
so let's not do it till next sprint. Then the manager went around my back when
I was gone for a day and gave the task to another dev. The dev, who caused the
mess, of course was able to fix it within an hour. Why did I say X amount of
time? To cleanup and make sure the bug stays fixed.

When you work with other developers, actually _work_ together. Stand up for
them, don't make bad comments about them, and always stick together when
you're asked to do the impossible.

~~~
sokoloff
If I understand your story correctly, that other dev accomplished the task in
some characteristically short amount of time, plus an hour for fixing a bug.

While you didn't specify what your "X" was, it sounds like the manager (and
the company) got a better outcome by going around you and it was far from
being "asked to do the impossible".

~~~
_asummers
I believe his point was that there's often a difference between finishing the
task and actually fixing the issue.

------
ska
The author seemingly misses an important way in which this can be looked at as
"real".

Some subsystems don't change much because they already do what is needed and
aren't broken. Sure, the code could be improved, but it's not important enough
to do (or at least, to do now).

Other subsystems don't change much because they are scary to change. If the
system is brittle and poorly designed, engineers may have very good reason to
be hesitant about changing it, and instead it is worked around.

So this latter case behaves very much like "technical debt" . This system
costs you engineering time every time you even think about touching it. It's
hard to reason about, it's hard to change, and over time these problems get
worse if you introduce workarounds in other parts of the system, because now
they are worse and harder to work with.

This is a very real cost.

~~~
samstokes
This is a good point, but I think it's very much in line with what the OP is
saying. Technical debt _hampers your ability to change_. Anything you're
scared of changing clearly fits that description.

Those workarounds that get created instead of changing the scary thing put me
in mind of the "scar tissue" metaphor that SapphireSun proposed elsewhere in
this thread.

~~~
ska
I'm not disagreeing with the main thrust of the OP's argument, but with the
statement that "Technical Debt isn't real".

I think that it often is best thought of as "real debt" in that it costs you
time and attention, and (at least some of the time) that cost compounds over
time. In other words, some of your engineering spend is just going to service
this debt, not produce anything useful. That's a very real opportunity cost.

------
ekidd
I'm unconvinced that accepting large amounts of technical debt allows startups
to react faster.

I've definitely seen startups that have _almost_ found a good idea, but can't
tweak it, scale it, or make it stable, because they're overwhelmed by
technical debt and even simple changes have become engineering death marches.

Letting your back-end code turn into a complicated, disgusting mess means that
adding critical features may become a multi-week nightmare. Which is then
followed by a series of additional multi-week nightmares for each successive
feature.

Now, this isn't to say that obsessive code-polishing is a good idea, either.
But startups require rapid iteration, and you can't iterate especially rapidly
when your code is complicated, badly organized, and poorly tested.

~~~
jmaistre
One of the most valuable startup skills is to know which kind of debt has a
low interest rate and which kind of technical debt has a high interest rate.
Certain things - lack of tests, poor build system, poor deploy system, very
poorly structured code - have a very high interest rate. Every time you create
bugs, you waste time tracking it down and fixing it. Every time you check
something in that breaks the dev environment for the rest of the team, you
create bugs. On the other hand, messy code that is isolated to one system, or
an architecture that has a bit of copy and paste, are usually not too big of a
deal. Going on some deep dive to create some "generalized framework solution"
is almost always an error.

~~~
hinkley
Some people talk about Reversible Decisions, and I think what you're saying
plays into that sentiment.

Unfortunately some people don't realize that in many situations not making a
decision is itself a decision, and so they don't always notice it when it
happens. That can be anything from the ones you mentioned, like testing and
tools, to authentication, auditing, localization, robust error handling,
resource/memory leaks, or monolithic designs that prevent scaling.

------
jaggederest
I don't believe that, even in the short run, taking shortcuts actually saves
you time. It's much like working 12 hour days - you feel more productive, but
you're not actually getting any more done on a larger scale. There's an
obsession with 'hurry up and get it done' that contributes little on a larger
scale.

I also don't believe it's possible to pick the 'important' areas of code _a
priori_ and make only those areas free of technical debt. Doing good work is
an attitude, a mind set, and something to practice - if you practice making
poor quality code, it's going to affect you across your work, not just in the
places that you do it.

I think that, by being professionals and putting aside the 'hack it out'
mentality, we can improve not just the code that we're working on, but our
mindset towards it. How many codebases have 'that scary part' that adds
background anxiety to the people that work on it? Is that something you want
to invite into your life on an ongoing basis?

Especially for things as important as integrations into external APIs - sure,
they may not change much, but in my experience you _really_ want to make sure
they're done right when they're _how you deliver your product to customers_.
Given how error-and-failure-prone many external APIs are, I expect a lot of
work there just to robustly handle the other end of your integration being
flaky.

I think that quality is something you can't 'bolt on' later. It has to be
built in, top to bottom, throughout your organization, code base, and personal
skills.

~~~
amelius
But often the choice is: do I implement this in an hour, _or_ do I spend a
week making a nice well-though-out framework for this, complete with test-
suite (which may take multiple iterations to reach perfection).

And you may pick the latter, but what if management wants to make a quick
prototype and turn that into a product later? At that point you'll still be
having the "technical debt" talk with your manager.

~~~
jaggederest
I think that's a straw man argument - the choice isn't between an hour and a
week, it's a choice between an hour and two or three hours. I don't think that
making a framework for every change is a good idea, but I do think that, if
you've only got an hour to work on something, you'd better make some quality
tests for it, because under time pressure you're _even more likely_ to make
the sorts of errors that tests catch.

That said, I'm not implying that you should slow down, just _do the best
possible work at all times_. Don't do a crappy job just because you're time-
limited - we all only have 24 hours a day, and there's always more work than
can reasonably fit in. The moment you start going "I am going to lower my
standards right now", you've started a trend.

I think it's interesting that people are always saying "hire the best possible
people you can", and then saying "but don't ask them to do the best possible
work they can do".

~~~
amelius
But a good programmer always sees a number of solutions to a particular
problem. Let's say he sees 10 solutions. Solution 1 costs an hour to
implement, but gives crappy code and he knows it. Solution 9 gives good
quality code, but takes a week to implement, and he then has to sell this to
his boss.

And then there's solution number 10, which requires the programmer to invent a
new programming language, and requires at least a couple of months to develop.
"You hired the best possible person for this job, so let me do the best
possible job".

I just bet most people here wished they could always deliver the best possible
code.

~~~
crdoconnor
>But a good programmer always sees a number of solutions to a particular
problem. Let's say he sees 10 solutions. Solution 1 costs an hour to
implement, but gives crappy code and he knows it. Solution 9 gives good
quality code, but takes a week to implement, and he then has to sell this to
his boss.

A good programmer will try and improve code the code _incrementally_ , and
won't bother trying to sell anything.

------
swalsh
"Financial debt, however, accrues interest and hurts more regardless of what
it is incurred for."

I'd disagree, I think all technical debt accrues interest (similar to
financial debt), but the interest rate is different. As the example about a
usps api demonstrated, that has a near 0% interest rate. Of course if you were
ever to need to update it (maybe usps updated its api) you'd get hit. A bad
domain model has a high interest rate. All the ideas are the same though, i'm
just being persnickety :D

~~~
dalke
A problem with comparing the metaphorical debt of technical debt to the
financial one is that interest rates can be negative.

In addition, the term "debt" also applies to moral aspects, and not just
financial ones. A builder may come back and improve something not because it's
good for the employer or has financial benefits, but because of a belief that
quality is good for the soul of the builder. That is also an aspect of
technical debt.

Regarding the original article, it says tech companies are "successful because
they got a product to market fast and at the right time". The "fast" is
incorrect. Companies are successful if they are at the right time. If a
company (like GO Corporation with pen-based computing) is fast but too early,
they they are not successful. If a company (like Microsoft with Excel) is slow
but eventually gets there, then they are successful.

"Fast" is therefore irrelevant in the face of "the right time." It can be that
the right time is "as soon as possible", but that's not intrinsic to success.

~~~
TheOtherHobbes
>If a company (like Microsoft with Excel) is slow but eventually gets there,
then they are successful.

Excel was successful because Lotus decided 123 had so much technical debt it
would be a good idea to "upgrade" the old assembler code to C. This took at
least a year longer than planned, and introduced a lot of bugs and
incompatibilities.

Meanwhile Windows had arrived, and the planned Windows rewrite of 123 never
happened as scheduled.

So it wasn't so much that technical debt killed 123. But _poor management_ of
technical debt certainly did.

Effectively the C rewrite was a complete waste of time, and Lotus should have
aimed for a Windows release as soon as they could.

It's nice to be able to say this with hindsight, but it was doubtless much
less obvious at the time, when Windows was barely considered a mediocre visual
DOS shell, and certainly not a serious OS.

Bottom line - you have to be smart, prescient, and a little lucky to manage
technical debt. It's not just about getting the code right - it's making
decisions with educated guesses about where you may be a year or two from now.

And _that 's_ hard.

------
ColinDabritz
I don't think the metric 'any code that decreases agility as the project
matures' is quite the same thing. I think most code lowers agility, as it is
increasing complexity and the number of interactions and entanglements across
your codebase. Adding features decreases agility. These are not 'technical
debt'.

I always enjoy Ward Cunningham's discussion of this:
[http://c2.com/cgi/wiki?WardExplainsDebtMetaphor](http://c2.com/cgi/wiki?WardExplainsDebtMetaphor)
(Ward first used the metaphor)

Specifically, he is NOT talking about 'dirty code' or just badly written code,
that's taking shortcuts and I believe it is never a good idea in software.
We're talking about building good code but doing so before we fully understand
the problem, often with the aim of learning more about the problem, especially
from user feedback.

What I take Ward's discussion to mean is that "technical debt" is accrued when
writing code for a problem you do not YET completely understand (e.g. almost
all 'first pass' code). The debt occurs when your code's existing
understanding is static (because it is in source control), and your teams
understanding grows. The difference is your debt. You can continue building on
the code's not-quite-right understanding for the moment which is carrying the
debt forward and paying the costs of fighting a not-quite-right model, but at
some point it becomes worth while to re-factor based on what your team has
learned about your problem, and thus pay off the debt.

~~~
spronkey
I don't necessarily agree that adding features decreases agility. Sometimes it
can massively increase agility - especially if your product is built in a way
that a new feature can immediately gel with other features.

But apart form that, absolutely. Technical debt in the article isn't the
technical debt that was originally coined.

I still think the common meaning of technical debt is just as important
though. Code that can't be taken forward, for whatever reason, costs its
owner.

------
svdree
In the past 15 years I've been in a situation twice where shipping something
NOW was more important than taking the time to do the needed cleanup. Simply
because the competition was breathing down our neck, and taking a break to
refactor stuff would just give them an opportunity to bury us. And who's going
to care about your code quality then?

And it wasn't just crappy web apps or throwaway MVP stuff. The first one was
in medical systems, where the suits figured we had a 6 month lead on our
closest competitor, the other was in consumer electronics (navigation
devices), in the time that competition was still stiff in that sector.

In both cases it was decided that releasing something was more important,
knowing full well that we had to pay the cost later. Of course not everyone
agreed with it, since no one likes having to work with legacy crap, and
everyone and their mother always wants to refactor all the things, but guess
what: code quality is not the goal of your company, making money is.

~~~
TazeTSchnitzel
> rushed software

> medical systems

Oh no.

~~~
angersock
It's more common than you might think.

Most software, especially middleware and EHRs, are the worst sort of
enterprise garbage.

------
Animats
The article applies mostly to short-lived webcrap and appcrap, where time to
market matters. There's software where reliability matters more than features
- databases, for example. Source code repositories. Banking systems. Soon,
automatic driving. (The coming "Internet of Crappy Things" is a real worry.)

~~~
jaggederest
I think that quality matters even in 'short lived webcrap and appcrap' \- you
only get one chance to convince your customers to trust you, and if your
application even so much as _behaves subtly wrong_ they're gone. I think
that's the class of error that 'hack it out' most causes - it's not an
application error, it's an error of logic or off-by-one or floating-point-
math-where-it-should-be-exact.

------
titzer
I hate to put it this snarkily and I fully expect karmic blowback, but I'll
just go out on a limb and say that what we need more of is not hastily shipped
crapware that barely functions and if successful keeps a legion of smart
engineers busy, cursing, hacking, grinding teeth and tittering.

No, what _you_ need is more hastily shipped crapware to capture markets from
your competitors so you can make more money and disappear. Hastily shipped
crapware has enabled lots of new and interesting things. It also keeps 10x as
many engineers busy serving it as would moderately better thought out,
slightly later shipped software. Babysitting crapware isn't bad money for an
engineer, but it's cosmically questionable as to whether it really advances us
more than its opportunity cost. And hastily shipped crapware at scale is a
real giant energy problem. Take a look at the size of a Facebook datacenter
and tell me again how a metric fuckton of PHP is a good thing for the
environment.

------
varunjuice
IMO This is all you need to know about "technical debt"

1/ Poor code =/= technical debt. Far too often, poor code masquerades as
"technical debt"

2/ Good engineers do the right thing which is always a judgment call based on
circumstance & culture.

3/ Take guidance from your best engineers, and find a way for the business to
adapt. Much easier to change the sales deck or pricing today, much harder to
overcome bad technical decisions. No one ever said "I never knew that sales
deck or pricing would last this long" but many say this about software. Be
super careful & deliberate.

4/ Build things that are simple (not easy), and respond to demand. Focus on
movability & robustness, not "perfect" design.

~~~
moron4hire
Your #1 is spot on. Every "grind-to-a-halt" scenario I've been in has been
because we expected X number of users or Y amount of data and once we released
it turned out to be 100 times those numbers. The system you build for 10
internal users is going to look a lot different than the system you build for
1,000 users on the internet, and that's going to be completely different than
what you build for 1,000,000 users. That doesn't make the small system poorly
designed, it just makes it inappropriate.

~~~
varunjuice
Interesting. Not my experience. Every grid to halt scenario I see or hear of
is just bad software decisions made under haste without deliberation, or
foresight beyond initial launch (no attention paid to supporting it, let alone
scaling)

Ergo, in your scenario even with 10 users, the application basically died
under its own weight under nominal use.

------
EvanPlaice
So... be agile agile agile... but, not really.

Don't waste time trying out the latest-and-greatest cutting-edge development
techniques. Except SPAs (Single Page Applications) because those (somehow)
take less time to implement and are 'easier' to iterate than a traditional UI.

Don't waste time perfecting the data models. Unless you're talking about data
structures (ie they're _totally_ not a type of data model) because your data
structures should be perfect from the start so as to avoid the technical debt
of modifying them later.

Don't waste time enforcing the SRP (Single Responsibility Principle). Unless
you're talking about 'siloing areas of concern into microservices' because
splitting responsibilities (and designing custom APIs to drive them) isn't
just another approach to enforcing SRPs. Designing APIs that connect your app
to it's dependencies in a manner that won't change (and break things) later is
easy right?

So, code, code, code fast. Don't waste time early on developing a sane
architecture, except when you want to spent time developing a sane
architecture early on to iterate quickly later.

Forgive the sarcasm, this isn't a troll. I'm just pointing out the blatant
contradictions.

The only valuable advice I can grok from this article is. Disregard TDD, build
a MVP, push it into alpha/beta ASAP, fix bugs later.

------
dccoolgai
From years of experience, I detect in the tone of this piece a certain notion
that product managers / non-technical people tend to form when working with
developers - namely, that developers _don 't_ care about speed-to-market and
would rather agonize and winge over perfect architecture and coding
standards... What I think you'll find, more often than not, on the business
end of this attitude is a developer(s) patiently trying to explain that speed-
to-market _is_ , in fact, directly related to the technical debt accrued on
the project for all but the most static and inconsequential things. We must
think and communicate about technical debt the way we do to keep errant PMs
from drifting off into the Ice Cream Sea of Candyland where all of there half-
thought-through ideas they demand be implemented immediately by cutting all
corners have no impact on the _next_ set of half-thought-through ideas they
want implemented.

------
qyv
There are some things I agree with in this, however I think the context in
which it is presented is flawed. This is particular: "Technical Debt is a
Positive and Necessary Step in software engineering" is just incorrect. If
technical debt was positive and necessary we would call it Technical Credit.

IMO a better context for this would be: real software engineering requires
compromises. There are a number of competing factors that need to be juggled
in order to be successful: time, money, complexity, quality, etc. The point
should be that you need to balance these factors, not focus on one above all
else.

------
georgemcbay
Ehh... what's this "we" stuff? I think the way a lot of people look at
technical debt is correct, not taken from the perspective the author seems to
have where debt is always bad, but rather taken from the perspective that the
term "debt" is meant to convey.

Financial debt (contrary to the implied sense I get from reading this article)
isn't always a negative -- business loans and even VC capital are forms of
debt without which many companies wouldn't be able to exist, mortgage debt is
debt without which very few people would be able to buy a home. These are
useful tools. Likewise, accruing technical debt is often just part of the
process of writing software, especially when "bootstrapping" new projects. In
moderation, it isn't bad at all, but like financial debt, you do have to
manage it, see it as a risk factor and not let it spiral out of control or
else it will become very destructive.

------
ssi1111
Either this was poorly written or the author just doesn't get it. Developers
shouldn't do TDD or 100% code coverage because they want to build a perfect
system; developers should do TDD because they understand that they can never
build a perfect system and the T in TDD protects them from complete failure.
This means you never attempt to build a perfect system; you only attempt to do
just enough. What is just enough? It is the amount of functionality to make
the tests in TDD pass... never the amount of functionality to make others
'fall down on their knees and claim “we’re not worthy!”' Thought I'd also add
that technical debt is unavoidable, but we realize it is not OK to have
technical debt (the article concludes that technical debt is OK) and that is
why we back it up with tests. These tests are like collateral for a loan
(technical debt).

------
mbrock
A simpler way to look at technical debt is to ignore all kinds of dubious
notions of "quality" and "correctness" and focus on lines of code.

The more lines of code you have, the more stuff you have to maintain and
understand.

Of course this is pretty stupid, but it's stupid in a way that sometimes leads
to insight.

If your application consists of 1000 lines of code, you can rewrite it in an
afternoon.

Also, cleverness can create its own kind of debt. Even as you believe you're
working on reducing debt by creating some clever and sophisticated
abstraction, you are actually just making it worse. I think this happens all
the time.

That's why my basic, fundamental approach to software development is "throw it
away and replace it with a simple shell script."

------
brlewis
Can someone please tell me the audience for this essay? Is there a company out
there where they're so careful to follow good practices and control technical
debt that they're erring on the side of too much quality? And are they hiring?

~~~
vorg
> Can someone please tell me the audience for this essay?

There's a clue in this quote:

> The most successful cities in the world, such as New York, London,
> Vancouver, Sydney, etc

A big city in each of the 4 largest native English-speaking countries of the
world, in descending order of population.

------
kstenerud
This has been my experience in the startup world.

My startup went from a few scribbled notes on paper to a full app in the app
store in three months, including 50 lessons, 6 mini games, and a
challenge/achievement system.

Naturally, I had to cut a LOT of corners to do that, and accrued a ton of
technical debt, but I was able to keep the high level architecture relatively
supple, and as a result tackle the various messes individually rather than as
a whole later.

It paid off. Or architecture has since changed twice over so none of the old
code remains, but we're strong on investment, have lots of people, and are
poised to take over our target market. And we got app of the year last year.

~~~
a8da6b0c91d
I'm a firm believer in the adage "Build the first version to throw away; you
will anyway."

[https://en.wikipedia.org/wiki/The_Mythical_Man-
Month#The_pil...](https://en.wikipedia.org/wiki/The_Mythical_Man-
Month#The_pilot_system)

I feel like that's it's own idea and should not be confused with technical
debt. The article seems to make this conflation as well.

------
drawkbox
Minimizing technical debt before launch or major milestones is huge because,
on occasion, that debt can compromise all future estimates/dates/milestones if
it is not addressed.

I think developers, including myself, like to get things right before launch
because fixing it after launch is harder, if not impossible once other
emergency/technical debt comes in and starts layering on top of that debt.

If this goes on for 1-2 cycles, before long your app, backend and internals
look like a shanty town that no developer wants to enter.

Sometimes I wish code was visual like buildings, you could more easily see
quality that way. Mostly though you have to believe in your
developers/engineers that what they are building is a mansion/building you
want not a shanty town dwelling that is held up on duct tape and silly putty,
yet the technical pressure/debt put on is largely coming from someone who
can't see the visual representation of the system.

Developers can only be MacGyver for so many release cycles before instability
strikes the system down if management is not careful.

There will always be some amount of technical debt but developers do love to
get things done and out the door as fast as possible. We like to do so with a
minimum amount of technical debt as it is a constant battle against
time/market/cost with quality.

------
bshimmin
"This is why single-page applications have grown in such favor over the past
few years; they allow quick agility at the UI layer without the need for API
changes."

I haven't seen anyone else comment on this sentence, but I'm baffled by it.
The first and second parts don't seem in any way connected, nor at all in
keeping with my experience of building SPAs - the UI layer is often
intricately complicated and every bit as hard to iterate on as an API!

~~~
shangxiao
Not only that but I've found SPAs to be more complex than their traditional
counterparts, mainly due factors like: the extra layers & complexity involved,
churn rate of & lack of maturity in JavaScript frameworks, lack of integration
with backend of choice. Of course there are advantages to SPAs and this
generally is my choice of architecture, however I definitely wouldn't say that
SPAs are more agile at all.

~~~
collyw
yes, usually you end up a lot of MVC on both the front and back end.

------
kybernetikos
Firstly, the definition of technical debt as anything that reduces your
ability to change in the future rings true, and is definitely a good way of
thinking about it.

And I accept that there are times when you can move faster by accepting
technical debt.

However, I'm always uncomfortable when this view is preached, because I think
that while all these things are true, they are rare. The most common case is
that when corners are cut, or 'tactical' solutions are adopted, you begin
paying for them within a week, often before you've even finished implementing
them. Another common case is that doing something in a way that allows future
change is almost no extra effort compared to taking on the technical debt, but
the vision or mental effort (or political will....) isn't there to even try to
see things in a new way.

So sure, sometimes we should embrace technical debt wholeheartedly, but most
people are already too far in that direction already. I'd rather read articles
about people who spent a little extra time thinking in these situations and
came up with a solution that was quicker to implement than the original plan,
with less, simpler code and fewer bugs. I think such things happen just as
often as technical debt producing good outcomes.

------
braythwayt
Half of my shortcuts are wins, and half are ridiculous sinkholes of time.

The trouble is, I don’t know which half is which until it’s too late.

------
omouse
>Technical debt is ok, and often a solid product strategy. The importance is
getting to market.

Apparently they're using Rails or PHP at Bigcommerce. If you're trying to get
to market as fast as possible then Rails makes sense but what goes with Rails
is TDD. You really shouldn't have too much technical debt when you're using
Rails or Ruby.

On the other hand, if they're using PHP then I'd bet a lot of money that they
have a lot of technical debt because they hired poorly skilled developers who
were able to push through some code that _looks_ like the feature requested.

At some point, you will be crushed under the weight of your own technical
debt. The race is whether your startup will die before that point. The author
sounds like he's trying to get acceptance that there will _always_ be
technical debt. How about letting your engineers working on refactoring and
making things nicer?

Facebook could have been crushed by their technical debt but instead they let
their engineers loose on the code base. That's how they've come up with Hack
lang which is type-annotated PHP, and that's how they've come up with flow,
the javascript type checker. This is why they made it a mission to allow
developers to be able to fix and deploy some code within 1 week of starting a
job. All of that forces them to fight against technical debt and to keep
themselves in the game.

That's the real issue here; sure it sucks creating technical debt in an effort
to get to market first, but it sucks even worse when as an engineer you aren't
allow to tackle the debt at any point or are only allowed to tackle it very
rarely. Efficiency is what will keep the dollars rolling in.

A recent example involving Google is Chrome. People are actively switching
back to Firefox or another browser. There's bloat in Chrome! How's that
possible?! My bet is a product manager who isn't allowing the engineers to
fight the technical debt in the code.

------
aaronbrethorst

        Systems take too long to get to market, which causes
        marketing efforts to stall or become irrelevant, and
        competitors beat out the startup to an offering.
    

I disagree. Well, maybe I agree in part, but I feel like this misses the
forest for the trees. Getting to market fast helps you get in front of users
(and prospective users) faster, which—assuming you're listening to them and
iterating—helps you achieve product/market fit before you run out of capital
or a competitor does the same.

Wikipedia has a bunch of great links to more on the topic if you're unfamiliar
with it:
[http://en.wikipedia.org/wiki/Product/market_fit](http://en.wikipedia.org/wiki/Product/market_fit)

------
crispweed
Of course code quality is important, but some good points here, and I agree
that 'technical debt' is quite different from financial debt. For example
(beyond the points made in the post) maybe you have 'technical debt' on a
bunch of code that becomes irrelevant and gets deleted (or reimplemented
completely differently, or whatever) so that you never actually have to pay
that 'debt'. I quite often find myself doing a kind of 'just in time
refactoring' at the point where it becomes clear that code quality issues
actually make it difficult to think about what the code is doing, or implement
necessary changes.

------
SapphireSun
Maybe instead of calling it technical debt, we should call it scar tissue if
you want to focus on the agility aspect.

------
abakker
I'm going to add a comment about non-software technical debt. Think about
technical debt in residential home construction. When a home is built, it
requires a footing, a foundation, framing, sheathing, electrical, plumbing,
insulation, roofing, etc. However, homes are typically designed "statically"
in that they don't frequently change shape.

As a result of that, when it comes time to renovate the house, the workers
doing the renovation frequently find that nothing about the construction of
the original house was designed to make it easy to extend or add to the house.
even things as simple as adding light fixtures can require running wires all
through the house back to the electrical box, cutting holes in walls, patching
walls, moving insulation, etc. When you go to add rooms, you find that the way
the foundation was poured means you'll need to remove existing foundation
drainage systems to add new footings, add new foundation, add new drainage
etc. Then, tear everything apart to add more electrical and plumbing. and
finally, tear apart a big portion of the roof to merge the shingling on the
roof.

Houses _are_ static, and thats why we tolerate building things this way. We
can't predict how they might change in the future, or what the needs might be.
If you could/did, you could mitigate almost all of those challenges I
mentioned earlier.

In software, we do know that it will change, and we frequently can predict
where and how those things might attach. Because we can predict those things
means that we should design our software to be ready for those expansions as
well as possible to minimize major structural changes to the whole
applications in the future.

------
auganov
The way I look at it, is that "doing things right" is a risk. It will always
equal faster "speed-to-market" in the long term. I think we're just afraid to
admit that "doing things right" very often ends up not working out. At all. If
only it were so simple, that we could just take a little bit more time and
have that perfect architecture and test coverage. In reality we often end up
making something that's not "right" at all. Or worse - nothing.

I don't see taking on "technical debt" as being faster. It's just less risky.
You're more likely to have something that does something after that month of
work. Hence the common perception that it's faster. In an organization where
there's mistrust (rational or not) it's easier (or even better) to take the
safe road of "technical debt".

------
drhodes
By the by, there's a recent software engineering radio podcast on technical
debt:

[http://www.se-radio.net/2015/04/episode-224-sven-johann-
and-...](http://www.se-radio.net/2015/04/episode-224-sven-johann-and-eberhard-
wolff-on-technical-debt/)

------
SCdF
In a perfect world I agree. I feel however, that I'd be more successful with
slow more correct development over fast and loose development, because the
latter requires immense determination and follow-through, at all layers of the
business.

The most important thing is always to make money. The most important money is
the money you make this week, not the money you might make in a year, and you
have weeks of potential money queued. It's equation is never right to spend a
few weeks not making money so down the line you can potentially make other
money at a slightly fast rate. It's definitely never the right time to do that
over and over again to get the many small improvements that will make you much
faster in the future.

------
Schwolop
I'm so glad Bigcommerce is finally taking technical debt seriously, 'cos that
place is _full_ to the damn brim with it! (Some of it mine...)

That said, the only reason their business is where it is today is because of
shortcuts taken in the name of speed-to-market. In their case, the end really
did justify the means - eCommerce is ultimately a land-grab for market share,
and BC dove in hard, spent _millions_ on marketing and customer support, and
left Engineering to fend for itself. As an engineer, it sucked, but in
retrospect and looking at their success to date, I'm willing to concede it was
the right choice at the right time.

------
rsp1984
This btw is precisely what separates the good engineer from the great
engineer:

A good engineer can produce a good product under moderate time pressure but
will accrue technical debt in critical spots if more time pressure is applied.

The great engineer anticipates the change and will not strive for perfection
in parts that are going to be rewritten in the future anyways but instead just
make it do the job, while at the same time keeping things simple and flexible.
That's how they deal much better with deadlines and time pressure.

------
dasil003
I see a lot of wisdom in this article and I find myself nodding, but I'm
dubious whether it's effectively communicated from the article per se or its
just my experience dovetailing with the author's. The problem is that
"technical debt" is an analogy, and like all analogies, it breaks down. It's
never a choice between writing perfect code or hacking together the fastest
ugliest thing that could possibly work, rather all long-term software
development is a continuous series of tradeoffs heavily dependent on an
unknowable future.

Consider the center-point of this article:

> _I view technical debt as any code that decreases agility as the project
> matures._

Well, any given piece of code can have positive or negative value based on
what change you need to make in the future. You can have a perfectly factored,
elegant piece of code which becomes useless if the job to be done changes, at
which point you are better with _no_ code than the previously ideal code. On
the other hand, you can have a module which is ugly as sin, unreadable, and
horrible in every way, but it does a job that never needs changing, and it's
isolated enough that no one ever even has to look at it or consider it.

So the very judgement of the scope and severity of technical debt depends non-
trivially on the future. Individually design decisions can be critiqued, and
the likelihood of certain types of changes can be weighed out, and certainly
the best engineering and product teams are very very good at this, but the
fact is that the whole endeavor is terribly fraught and difficult to
concretize.

All that said, I think the author is absolutely right that engineers often
have a proclivity to polish some bit of code or architecture when their time
would be better spent elsewhere, but it's just a tiny microcosm of the problem
facing all startups: you need to build a money-making machine, and you have
infinitely many dials to turn, with only a handful of (hopefully) smart people
on a very limited runway. How do you make decisions day-to-day about where
your greatest marginal utility lies? I don't think there are any rules of
thumb that are globally applicable. If you are lost, a blog article is not
going to help you. The only hope is to gather feedback as widely and quickly
as possible and be brutally honest with yourself.

------
johnrob
I'm starting to believe that debt is the wrong metaphor. Imagine you have 1k
in debt and 2k in the bank. You're free to pay down that debt, so you do. If
you later realize that you actually need that 1k used for the debt, you can
simply take out a new loan and effectively undo that step. This is precisely
where the tech-debt analogy breaks. When you invest a month into fixing tech
debt, you can't get that month back. That decision is final.

------
mikekchar
Making decisions about technical debt is hard. Anybody who tells you otherwise
is someone you want to stay away from in a work environment. Every single one
of the decisions you make is context dependent, sometimes massively so. You
need to know where you are and where you need to get to at every step. Only
then can you make good decisions. For what it's worth, here is my list for the
places where most people get it wrong.

1) People lie about what is required. Anyone who has been in the industry for
more than a token amount of time has experienced the PM who says that they
need X+100 when they really need X because "programmers are lazy". Similarly
everyone has worked on a team where one or more of the programmers are more
interested in building their beloved architecture than solving the problem at
hand.

2)People don't listen to the needs of others. Very often they assume problem
#1 exists ("They don't actually need that") and blindly forge ahead without
paying attention. They play whatever political game that is required to force
the other side to follow their approach.

3) People make mistakes. Often this is due to a lack of experience, but
sometimes it's just because the problem is hard. Some people make mistakes
more often than others. Good management will recognize those that are making
good choices, but sometimes you have to let people crash a few projects before
you realize that they don't know what they are doing.

4) Choices are made at the wrong level. With all of the other points I've
made, it is exceptionally tempting to move all the decision making to someone
who acts truthfully, listens well and has a good track record. However, the
information required to make a good decision can be at many levels. Sometimes
you _need_ 100% test coverage of something and only the programmer will know
when this is going to happen. Sometimes you _need_ to deliver tomorrow even if
it doesn't work at all. Only the PM will know this.

In order to build a team that executes at the highest possible level, you need
to have people who work well together, trust each other and are competent. If
you do not have this, then success will likely be a matter of chance. No
amount of heroics from a single person can reliably fix the issue -- and often
such heroics just make matters worse because they result in the behaviour
listed above.

------
AshFurrow
Sure, strategically taking on technical debt is sometimes beneficial to the
company – just like sometimes taking on personal debt can be beneficial, too.

I think that discussions around technical debt really lack any mention of
technical _credit_, the opposite of debt. Just like how you can take on debt
in your codebase, you can save up credit, too. In an ideal world, you would
always have savings so that you don't have to take on debt.

------
overgard
I like the application segmentation strategy (when you can get away with it);
it reminds me of the unix philosophy but over a message bus instead of pipes.

Running things over a message bus is slightly more work than one large
application, but the upshot is that it lets you experiment with new
technologies and ways of doing things without betting the entire
product/company on it.

------
voidr
Unless you have infinite amount of time, you shouldn't refactor code you
didn't need to touch in the first place.

When you have a large enough codebase, you will always find bad code if you
look long enough, it's pointless to waste time on that. You should only
refactor code that you needed to touch in the first place.

------
ww520
Incurring technical debt early on is fine. A large portion of the code for new
ideas or new venture are thrown away anyway due to misaligned market or
product fit.

However, management need to understand technical debt and their impact on
timely product delivery in later stage of development.

------
mirceal
technical debt is actually worst than financial debt. imagine an interest rate
of x%. now imagine that one day the bank comes in and says: now your interest
rate is going to be 20x. you don't get a say in it and you cannot refinance.

also another mistake I've seen made over and over again is to say
stupidity==technical debt. If you're doing stupid things just to 'get things
done' you're doomed in the long run. If you've thought about it and made the
decision to cut a corner you should know why you've done it.

------
hibbelig
There is a related idea: refactor code that you need to change, don't refactor
code if there is no other change you want to make.

------
rifung
I agree with the author more or less at least with respect to compromises
between software quality and speed of execution. Code does not have to be
perfect, especially when it doesn't affect the end user.

On the other hand this is what I miss most about school, or perhaps just doing
things out of my own interest.

There was a time when I could appreciate the beauty of code and all I could
worry about whether my software was elegant. Then I joined industry and
everything changed.

------
alwaysmeh
This is a terrible article. The awfulness starts at the title, and continues
throughout.

What's wrong with the title: he asserts that "we" all defined technical debt
incorrectly, when (in my experience) there's no meaningful agreement on that
term. It's one of those terms that, if it's used, requires follow-up to be
sure that both parties are talking about the same thing. The author even
acknowledges this lack of agreement, but he asserts that we're all using it
wrong.

The author then proposes a definition: "any code that decreases agility as the
project matures".

Sorry, but there's no polite way to say this: that is, quite possibly, the
most useless definition of technical debt I've ever heard. Every line of code
decreases agility in one direction or another, every step forward is a step
past some other opportunity. Thus, a definition that conflates necessary
progress with actual problems is worse than useless. It's harmful. And
frankly, I have trouble imagining an intelligent person who would use it. At
this point I'm attacking the author a bit, but at this point the author has
attacked the entire world a bit, so it seems fair.

The author has made clear that he thinks he's smart, that we're dumb, and he's
figured out things we can't understand. So gross.

Captain know-it-all then proclaims, in bold font no less, that "The Most
Important Thing is Getting the Thing to the User". No. Fucking. Shit. We
fucking know that. We get that. Please don't do this shit where you conflate
the whole damned world with the one guy in your office who you're passive-
aggressively railing against with this awful awful screed.

Then this just gets into total dishit territory. We're supposed to not worry
about getting everything right, but god forbid we need some migrations along
the way, no... those aren't acceptable to this bloviation blowhard, we must
get them all right on version one.

I now have a better understanding why BigCommerce is about the fifth company I
think of when I think of places to host a shop. They're a fifth place company
that hires fifth place management.

And Shaun, if I'm correct that you wrote this because you're tired of hearing
your team talk about technical debt, then you are truly a horrible manager and
you should just fucking quit. I'm not a person who typically advocates
quitting, but this seems like nothing more than a passive-aggressive attack on
one or more of your engineers who mentioned technical debt or code quality
more often than you'd prefer.

And if you really just thought this was brilliant insight: you're an idiot.
You used a dumb definition of tech debt to justify an argument that showed you
don't understand the original metaphor. You are an impressively stupid man.

------
richmarr
Couldn't agree more, in fact I have an unpublished draft on Medium that makes
similar points. Happy to share if you're interested.

~~~
throwawayaway
oh please, please share it.

------
wcummings
>For instance, if you’re using a relational database, and your models are
improperly structured, this will cause you significant pain later on. If you
build a system using NoSQL that later needs to become highly relational, you
will incur massive frustration in the future.

I don't think this is what Linus was talking about...

