Beautiful Technical Debt
abdullin.com
abdullin.com
Instead let's call it "technical clutter", because that is what it is.
It's the equivalent of an unclean workshop with broken and unused tools lying around. You trip over everything, you cannot find anything, your tools hurt you or slow you down.
Managers need to understand that technical clutter is central in hindering and slowing development. Not a separate account that is not affecting work.
This is the interest you pay. 'Debt' captures the problem of it being an ongoing cost.
With "technical debt" you could argue that business demands coming down to "I want it NOW" will lead to slower or more work later, and give management agency in determining if that is in line with the value they expect to gain.
With "technical clutter", the problem is moved to the devs: They could just have, you know, "worked cleaner" to begin with (nevermind we never gave them the time to do so). It's their own mess that originated by their decision, not the mess caused by PMs or customer expectations. And if the mess caused by mess-inducing management tactics becomes too big, management would just fire "bad" devs and hire some newbies.
So ... I do get where you're coming from. With normal people, the difference in meaning would lead to better understanding. But management has a large amount of non-normal folks.
You'd regularly clean a building you live or work in. You probably won't do the same to a building you have to enter once a year for 10 minutes just to go in to change a light bulb. Even if it's dirty or cluttered, the ROI probably isn't there.
Not all debt comes with terms that allow it to be paid off "from time to time". Most personal debt does, but the debt that corporations deal with often has very strict, inflexible payment terms.
I'm sure it's not the final iteration of analogies we use to garner more budget or help clients understand that always pushing for the cheapest solution isn't the best idea. But I think it does a reasonable job. It abstracts away the finger pointing of "you coded it badly" vs "you never give us enough time to do it well."
Taking terms to a client like clutter, bad code, spaghetti code, and other more direct terms I've seen lead straight to uncomfortable questions about capability, experience, and so on.
I think if it's explained with the idea of compound interest it conveys the growing impact over time if it's left undealt-with, and it's an analogy most people are familiar with.
It's definitely easier to push back on taking a shortcut using the debt analogy than by saying it will force us to make their product badly and please pay us for the privilege.
I totally get what you're saying, personally I will always speak my mind and put my foot down where appropriate, I avoid working with people that constantly just push for more with less. Even then though people still often want things done and don't understand what they're asking for.
It's definitely better than the house-building analogy that causes eyes to roll so far back they roll out of the boardroom and down the hallway. Trying to explain how code complexity really works puts everyone to sleep and no one understands it anyway.
I'd be really interested in a compendium of boardroom analogies come to think of it. Could be a fun read.
Whereas the concept we are trying to get across is: we have accepted some things that are less than ideal (code quality) in order to gain in another area (probably time to release). A tradeoff, and more importantly a tradeoff driven by concerns outside of engineering's domain.
I might agree that the term is overplayed and watered down, but any replacement has to include the role that the business side plays in the problem.
Like, when we were a small company we were delivering our stuff with metaphoric bicycles, because they are cheap and good for the environment.
Then we updated to motorbikes for faster delivery.
Now our customer base has grown, and we have a lot more stuff, so we are updating everything to trucks, and need time to dispose the bikes that we do not need anymore.
Then finally, we have become an international company and need to update to cargo planes.
And when they try to blame the engineers that it is their fault and they should have been using the biggest thing from the beginning, you can say: You do not buy a 747 to deliver stuff to you neighbor on the same street.
Good luck with that. This won't work in most situations, because the people involved have moved on or are too busy to talk to you about something that will only benefit you, but not them. Most non-software engineers won't understand the argument of development velocity in the context of technical debt.
The thing that makes technical debt so miserable is that you are usually lacking context. Code comments can make a huge difference here. If a developer has to cut corners, the reason for the bad code has to be documented. Otherwise it is hard to judge if the code just looks bad but is actually fairly optimal, or if it is actually bad and a rewrite is encouraged.
(Public) building engineers, carpenters, archeologists, architects (that is, anyone that has a long time scale understanding, before and after their work) have certainly a good understanding of what "velocity" is and how it would be impacted by their options of intervention on a specific project for later interventions (and how it is today impacted by the choices of those that came before).
They don't call this technical debt for that matter.
With software you can avoid the "pay it back" part - simply by retiring the software entirely.
But you cannot avoid the interest - as long as you keep maintaining and supporting the software, the debt present within, will cause extra work and extra pain.
That recurring interest can accumulate to the point, where it's more expensive to pay the interest, than it would be to just throw everything away and start from scratch. But you can't retire the old code before the new code is ready to replace it - and you don't have the capacity to write the new code while all your effort goes into maintaining the old code.
Your existing developers increasingly burn out on maintaining the old code, some might even quit, and you are unable to hire new developers, since they'd rather sign up for another company that isn't that deep into legacy problems.
This is the dead end you want to avoid - and the best way to avoid it, is to get rid of any technical debt as soon as possible. It's okay to make the strategic decision to take shortcuts in order to meet a deadline or keep a customer - but letting the resulting debt accumulate is not sustainable in the long run.
Bullshit. Typical startup fails. So, typically all the investments to reduce future technical debt is waste.
Engineering teams make often a huge issue about technical debt, sometimes in companies where it looks pretty clear that there is no much use in removing that technical debt since future investments in the company/technology seem unlikely. I guess in these situations the problem is that the leadership is not really eager to communicate the real situation to the devs.
I agree with your second point, finished products/companies are finished. No reason to pay debt there if the pure maintenance (if any) is not impacted. But as with the other topic: That is often not the case.
On the one side of the coin you're right, it doesn't matter for a huge percentage of startups - until it does, and then it can matter quite a lot, very quickly.
Yes most startups fail so technical debt isn't a primary concern. But on the flipside if a startup becomes successful they'll have the budget and experience to clean up technical debt. Only at that point it's like repairing a car while the engine is running - when you're scaling fast, suddenly you have millions of new users flooding in, you can't take your systems offline and rebuild them on the fly - users demanding new features and improvements takes priority over fixing invisible stuff they can't see, etc. I'm sure you understand this.
I can think of a few companies who were big players in our local / national sphere who hit it off, got splashed all over as the next big thing, and their systems totally failed during their big events, or were seen as industry leaders only for a breach to sink them overnight.
I see part of the problem is technical debt often only gets raised retrospectively, when it would take huge efforts and expense to deal with. It doesn't take an insane order of magnitude of time to move a little slower and make more calculated decisions to build something with scalability and longevity in mind. A sensible balance should be struck between velocity and engineering. Technical debt should be raised early in the process and used proactively in decision making.
I suppose it doesn't matter if you're an investor or owner just trying to get ahead of the market and sell it off for profit, you can flip Gartner-as-a-Service products all year long and still come out ahead even if a good portion of them fall over their own feet at some point in the future.
Just to say that "debt" is not a physical, inescapable fact, it _can_ be cleared, fully, or partially (interest-wise for instance).
The concept of "debt" is not much clarifying/simplifying the concept, and "interest" here has no significant/similar meaning as in financial matters. The analogy stops quick enough.
Legacy is in itself a slightly better analogy, as it conceals away that it is good or bad in itself.
If the system that the debt is part of as a whole is increasing in value, then hopefully the relative amount of debt and its associated interest diminishes over time.
I'd say the real question is will the shortcut that leads to technical debt going to yield greater returns than the cost of the debt. And if so, over what time-frame?
On the flip-side, will rejecting shortcuts and avoiding some technical debt result in getting to market later resulting in less income and losing a competitive advantage? Were these penalties far greater than cost of the shortcut?
Relapsing back to the good ol' car analogy, it might be far more prudent to take on a car loan than buy the car outright. If the interest rate is low enough that it's below inflation, it's less than what your transportation costs would be without this vehicle and/or it's less than what you could be earning as interest on the money you would have put down to buy outright, then there is no harm in taking on that debt. In fact you might say a decision not to take on debt in any of these cases would be foolish.
I guess the moral of the story is that not all debt is bad or equal.
It’s much better to have a working product, customers, investors, etc with some code that isn’t perfectly DRY for example, than academically perfect code for a product that’s 20% functional and no one will ever know exists.
In the real world we have limited resources when starting things and you sometimes have to pick between those options.
If you have something new and very limited resources, get something going and refactor it later.
I'm talking about removing things which cause extra work, are more error-prone, do not scale, and/or demotivate the team.
Those are two different scenarios and you can’t defend one with the other. Stop apologizing for your old code and just fix it.
If only in teaching new comers of a potential (apparently) edge case.
There’s a related thing:
Hacks, workarounds and quick and dirty fixes have to go somewhere, because they happen anyway. It’s better to have space for them, then to mix them with organized code.
Now you have a place (or other convention) for inconsistency and scarred code. It’s more honest, obvious and easier to fix.
What the post fails to call out is that many of those problems simply might not exist anymore. That tree may have had to weather a freak once-in-a-thousand-years stormy season, and has structural baggage as a result; but if that tree were to grow again starting today, a repeat season may never happen and the tree would end up looking different.
One way we can consider technical debt is the extent to which the current solution differs from an (often mythical or at least hypothetical) ideal solution. How different would it look if we built it today, with only today's constraints, rather than all the historical ones? How much is that historical baggage getting in the way of us moving forwards?
You can be explicit and explain why things are as they are and if we have to do some extra work because of code addressing no-longer-relevant-use-cases, that’s just it.
No need to call this TD. Be clear and explicit.
I think in most cases, Technical Debt is a much abused term to bullshit and cover up past mistakes. TD sounds much better than mistake and it sounds so ‘inevitable’, so you can’t be blamed.
It is way too easy for an engineer to lose himself in the microsphere of his project, wanting to make better software for the sake of better software. That often clashes with the goal of the organization - the only relevant result is whether the software works or not (or, in the case of most non-critical applications, what percentage of software works).
The downside is that technical debt can massively increase development time - and there is no way to measure how much time you're losing because, to know that, you would have to be free of technical debt in the exact same scenario.
I see only pain and problems when I see a technical debt. Not that these need to be fixed/cleaned/paid or do not teach us a lesson, but let us agree on not calling it beautiful.
lol. Like every other mess.