Hacker News new | ask | show | jobs
by wokwokwok 1588 days ago
Controversial idea:

Technical debt is something that 'business users' don't need to or want to care about.

If you're having conversations about technical debt, you've messed up, and you will continue to have unsatisfactory outcomes until you stop doing so.

You can't tell people; here is a dial, you can pick 'fast and you're screwed later' or 'slow and careful now'. You're setting yourself up for failure; they cannot pick 'slow and careful', because that's not their job; their job is to quickly deliver value/outcomes/whatever.

Almost no one has a job of 'go do this really slowly and carefully'.

They will always pick fast, and it's your problem later.

So... don't do that. Instead, say: this is how long it will take to do.

Not "if we rush we could probably do it in..."; no, if you say that, then why are you not rushing now? Do you not care what the business wants? Do you not have 'skin in the game'?

Say: This is how long it will take, we estimate. If you want it faster, we can cut some features.

Then, do enough of a good job so you can continue to deliver value in the future.

That's literally your job.

Doing a rubbish job as quickly as you can is not your job. Not ever.

You cannot abrogate responsibility for doing your job properly by saying "but I was told to do this", if you literally gave them the choice of A or B, where one of those options was "you have to pick this one, and it lets me get away with doing a rubbish job of it".

That's YOU choosing to do a rubbish job.

...and to be fair, yeah, there are situations where someone will come and tell you "no, do it now", and that's what you have to do... but you also have to come and clean up afterwards. Not because you're told to, explicitly, because... it's your job.

21 comments

One thing missing from your statement is that plenty of technical-debt comes from things that were done properly the first time, but since then assumptions have changed, or the business is different, or the customer's expectations have evolved, or a competitor has upped their game, etc. This makes the so called perfect solution then, imperfect now - i.e. technical debt.

There are always trade-offs, and a good partner in any team/business will help those be articulated.

One thing that is important for any engineering team is to have a certain amount of capacity either permanently dealing with technical debt, or regularly dealing with it. Judging the amount of effort that goes into fixing it depends entirely on the amount of 'interest' you're paying. That isn't always easy to measure, but a good senior engineering team will have a sense of when things are getting hairy.

The idea that it's avoidable is unfortunately wishful thinking for any project of a substance.

> since then assumptions have changed, or the business is different, or the customer's expectations have evolved

Hilarious. In the IT department(s) of my Fortune 150, they still do picture-perfect waterfall development, with outsourced teams, writing Java. The application is set in stone when it is signed off in production. Things change? NEW PROJECT. Another 3 YEAR CONTRACT please.

And, yes, as as matter of fact, it IS utterly maddening to be one of the few people who bother to try to say things could be different, and watching nothing change, because so many people's jobs are literally built on their world working this way.

So build the time of fixing tech debt into your estimates. You're right, you can't avoid creating tech debt, but you can absolutely fix it while you're mucking about in that code anyways.
This is ideal. At times though there will be pushback by engineers and product teams drunk on the high of delivering fast and often.

It also requires knowing the approximate amount of debt that may be involved in any given work. Or else actual work may far exceed estimates so often they become meaningless.

Both of these concerns are a part of maturing as a software developer. Managing expectations, leading your team, estimating - these are soft skills required by a senior or above software engineer.

Estimates, as a rule, are never terribly accurate in the first place, often because of tech debt - adding in cleanup won't make them much better or worse. To give any kind of estimate in the first place, you need to be fairly familiar with the code, which includes the crufty bits that count as tech debt.

The other thing is that technical debt is not always bad. It's just another stat to manage along with budgets, ROI, available engineering time, customer engagement, etc. etc.

If you have a product that's nearing end of life and you can boost its value for another year with a quick hack, then do it. If there's a system that really needs refactoring and is getting harder to extend, but still works fine as it is, then you leave it alone. If things have gotten a little curly but are still serviceable, just roll with it. You don't just trash everything, obviously, but a year from now when you retire that codebase, any extra time spent on it now will be wasted.

In your new flagship product that you have no plans to replace for the next 5+ years, you take the extra time to keep everything nice. You re-engineer whatever needs re-engineering to add that feature like it was always meant to be there. You refactor the smelly bits of the code. You push back entropy to keep it shiny because it's likely to be worth it.

> technical-debt comes from things that were done properly the first time

So its not tech debt, its a complex system that takes longer to do things in future. "Bad tech debt" is like credit card debt, short term decisions made at expense of the future to impulsively satisfy immediate needs. "Requirements change over time but it was done right at the time" is like a mortgage and you need to move to a new town. Its entirely reasonable to have a slightly cumbersome payoff process because it was well chosen decisions. Still harder to pay off, and may incur more debt, but as long as its reasonable.

And this is why I call it technical tax. It permanently eats away at a % of your engineering capacity.
Controversial because it's disconnected from reality. You're putting ALL the responsibility on devs as if they are free to present any estimate they like that will then be then accepted without questions or negotation by management. In this fantasy land management is presumably operating in a vacuum with no pressure from customer deadlines, costs, investors, long term product roadmaps etc.

I don't know about you but that is typically not at all how things go at my job.

I can present a 3 week estimate to manager, he will say why 3, seems like it should be easy??, Bob says it would take 2, can you provide a breakdown of the estimate, why does estimate have 3 days for "unforeseen obstacles"?, let's cut that out. We only have 2 weeks but we can't cut scope. 1 year later everything takes twice as long as it would in a cleaner design, management is wondering why dev productivity is low and won't allocate time to maintenance (we can't spend even MORE time on some refactor thingamajig, our productivity is already low!!). Meanwhile im trying to figure out some monstrosity of a codebase written by an engineer who left last year, and also neglected to document their code (unfortunately their manager felt 1 day for documentation was unnecessary). I think this is closer to the scenario most devs operate in. In all but the best high trust scenarios, every estimate is a negotiation.

In reality technical debt is 10% a communication problem (as this and many blogs like to frame it) and 90% a "do you trust your mechanic to have your best interests at heart" problem.

In your scenario your manager appears to be your adversary and not your manager. Those comments are what I would expect from a stakeholder, but not a manager. Your manager should provide a unified front to business and senior management. You two should agree on the correct approach. If your manager doesn't believe that your team should build things correctly and minimise technical debt then he's a terrible manager and you should leave.

Your entire scenario would be moot if you practised scrum and estimated the work effort as a team. Your manager might get a vote, but that's it.

> If your manager doesn't believe that your team should build things correctly and minimise technical debt then he's a terrible manager and you should leave.

If you or your manager believe that there is only one "correct" option and that technical debt should always be minimized (vs being balanced against other factors), then odds are you're bother either terrible or very naive. In almost every moderately sized piece of work, there are multiple options and there's a choice of which one to take based on various priorities (ie, the best option varies depending on multiple factors).

While true, this doesn't change the premise. Both parties should agree on the "correct" approach in the context of this discussion: minimising technical debt.
Your manager is always potentially your adversary: after all, they can fire you if they are unhappy with what they are seeing.

Not to mention that some managers simply are adversarial, period. When you apply to a company, you can rarely choose your manager, and sometimes cannot work under a different manager without leaving the company entirely.

I've had adversarial managers in the past. Unsurprisingly, the team underperformed and the culture was terrible, so I left. I don't agree that one's manager should be one's adversary. I've worked with many managers who work with me instead of against me. This is a crucial difference.
The real issue in a situation like this is the use of the Agile Story point BS to create competition between developers in order to have leverage exactly this to push back against the Engineering team with. You need to have a Dev-only meeting so Bob doesn't feel specifically called out and talk about how you all want to negotiate the interests of Product/Business with the dwindling engineering situation, i.e. Tech Debt.

Bob, and others like Bob who live to impress management with their personal 'agility', will implicitly feel more pressure to not go against the whole engineering team if you're able to reach even near-unanimity about what that strategy will look like, in this case, perhaps coming to agreement about how certain tasks will be pointed univocally, amongst other possible strategies. Your only obstacle at this point is a head of Engineering whose interested in their own career over and above his team.

Agile SCRUM exists, largely and for the most part in my experience, as an abuse to prevent this kind of 'collective bartering' on the part of Engineering.

Sorry to tell you this, but it sounds like you have a bad manager. Your story is like not how healthy teams operate, which in my experience actually are much more like the post you're replying to.
Thank you, really. It is nice to hear someone else acknowledge it. I'm going to start looking for a better job.
> Bob says it would take 2

Tell Bob I wish him the best of luck in this endeavor, he's clearly a better programmer than I am.

Bob can remain lucky for longer than you can keep your credibility intact (aka "markets can stay irrational for longer than you can remain solvent"). Ultimately, that stance gambles on Bob's luck running out and his lack of skill being exposed in time for you to profit from it.
Or realistically, bob looking good racking up tech debt and quitting before anyone needs to pay it off
I think the concept here is similar to the behaviour a lot of people exhibit when trying to say 'no' to something. Generally the 'no' is non-negotiable, but a layer of reasoning is added on top that invites the other person to negotiate.

Person A: "Sorry, I can't do this because of X, Y and Z."

Person B: "Well, can't you do X, Y and Z another time instead? This is important."

You never really wanted X, Y and Z to be part of the conversation, but now they're in it and you've been placed on the defensive. If X, Y and Z were never mentioned in the first place, they wouldn't be on the table and you wouldn't have to justify them.

Same as it is with stuff like tech debt and non-functional requirements. You want to do them, you most likely have to do them, so bake them in. Keep the tech debt and NFRs off the table but leave the features open to negotiation.

Obviously has to be within reason if you want to maintain credibility, so you've got to figure out how to prioritise your tech debt too. And sometimes that means you don't do any of this and you accept a bit of interest on that debt.

Tradeoffs all the way down.

Yeah I can see why that is controversial.

The assumption seems to be that a single developer has agency and is aware of and solely responsible for everything that's going on in the codebase that they may or may not have written.

I've been in a situation where I joined a new company and the code base wasn't looking good but my job as a new hire wasn't to redesigh and rewrite the guts of it. My job was to implement new features, one after another, usually without enough specification to even begin to estimate how long it's going to take when everything they eventually turn out to want is accounted for. The project was already very late. I tried to spend time fixing the foundation and pointing out its problems (including complete lack of tests) but I was told to stop because the customer wasn't paying for that time. The problems I pointed out went ignored.. until they messed things up in production a couple years later.

I'm gonna say they chose rubbish against my advice, and they eventually got what they wanted. Rubbish on top of rubbish, with lots of bugs and slow development.

"We build our computer (systems) the way we build our cities: over time, without a plan, on top of ruins." - Ellen Ullman
I disagree pretty strongly with what you've said here. Specifically, part of my job is to make sure my customer is aware of the options and the costs of each of those options. Doing things the faster/less robust way now will have a cost later (re-implementation of some part, etc). And then I do my best to convince them of the approach that I think is best. But only telling them about the option I think is best and _not_ discussing the viable/reasonable options... is definitely not my job.

Implementing a faster solution that will have costs later isn't me choosing to do a rubbish job. It's me helping my client make the best use of the available time/money.

When I hire a company to install a new heating system, they present me with various options; better/worse hardware, single/multiple zones, brand new hot air lines vs rewrapping existing vs using existing unchanged, etc. The person from the company may have a strong opinion on what is best, but listening to them and then making the decision I think is best is expected.

When you get a new heating system are any of the options "fake it til you make it?"

Would you pay for any of the options known to be unstable and will have to be replaced in a year?

What about the options that require HVAC staff to carry 24 hour pagers? When's the last time you got a whoopsie email from that manufacturer because of an outage?

I've had to choose between

- Installing a 3 port hot water line that has an extra, unused port for later (when we furnish the basement) and a cheaper, 2 port line. If we chose the 2 port line, it would have cost less now, but incurred additional cost (replacing it) when we furnished the basement.

- Using the old hot air lines (much lower cost, but less efficient), rewrapping the part of the current hot air lines that can be reached (middle cost, middle efficiency), and replacing the lines completely (higher cost, higher efficiency)

- Installing a reserve hot water tank (more expensive, but better able to handle load) or not (less cost, but could result in not enough hot water under load). If we went without the reserve tank and it turned out we were short on hot water on a regular basis, it would cost to add one in (overall, more than just including it at first).

None of those things are choosing between "doing a bad job" and "doing a good job". They are all a choice of how much we want to pay now vs debt we may/will need to pay off later. Ie, a parallel to technical debt. Technical debt doesn't always mean you did a shitty job, it could mean you took certain shortcuts because they accomplished what was needed _today_, but will incur additional cost _tomorrow_.

> Technical debt is something that 'business users' don't need to or want to care about.

Sometimes it's hard to tell your manager: Yes I know you want to track every single coding task in Jira, and you don't see any immediate value to this one, and I'm not going to dispute that, but I am going to do it and you "don't need to or want to care about it".

Sucks not to have that autonomy but it's real. That's when you have to justify the refactor, and not with potentially offensive statements like above.

It's also important that they know, so no one is surprised when the next release goes out with those changes and it turns out that an edge case wasn't tested. You don't want to have to explain that something broke because you made a decision on your own to clean up the code.

When you're getting permission to do something like that, management is deciding if the risk/reward tradeoff is worth it, and I think it's only fair to give them the opportunity to make that analysis.

That's why you sneak it in piecemeal as you go, and leverage the critical path of urgent things that aren't finished yet to get it done.
I had a boss once who had a Math PhD and could throw together spaghetti code to implement his ideas.

He would give me a task to do and would basically say "don't waste time making the code clean and nice" because he knew I had a software engineering background and didn't want me over engineering anything.

I would nod, implement it "the right way" anyway, and get it done in the same amount of time.

Because doing it the spaghetti code way always takes longer in the medium to long run, and often even the short run, anyway.

Not sure I agree with the theme of this take. Technical debt can be significant and take months to address on a large codebase. This take also places a lot of blame on the devs who have to work on tech debt, where in reality, it's often another dev who wrote the original code(usually several years ago, and no longer at the company). Things are more complicated than "just deal with it and hide it under a rug".
> Technical debt can be significant and take months to address on a large codebase.

I think the premise is that if you've got months of technical debt built up, you've already screwed up. If you (and everyone else on your team) refuse to ever take shortcuts, you'll end up debt free.

If you're already in a situation where you have mounds of debt, yes, you can't just increase your estimate for current tasks.

"If only everyone" is a version of the Prisoner's Dilemma. I don't think we've got that one figured out yet.

Besides, if your working style overly focuses on proper engineering while other things are on fire, the company could die.

The problem with me is many times I'm not aware that I'm introducing a debt while developing, only until it's reused or revisited that it's clear enough. Yes, even with code review process.

So even business users need to understand that there must be "maintenance phase" even for software, to pay tech debt, updating packages, patching / improving securities, etc.

Sometimes you just need to deliver quickly and cutting scope isn't an option.

Sure you can say that it's not possible. Then you get replaced by someone who's willing to take the necessary shortcuts.

What's important is to make it clear that you're taking shortcuts and that you will need time allocated to clean it up later. That's basically what technical debt is.

Lots of people have fought with technical debt for a long time, and if it was as easy as just being like, 'oh hey, we just do it next sprint' it wouldn't be a thing.

...it's not that easy. It's not easy.

I'm not saying it's easy.

I'm saying: If you do the easy thing, which is always choosing to leave technical debt behind, and waiting for someone to come and tell you its ok to deal with it... you're going to have bad long term outcomes in your project.

Part of your job, as an engineer / developer / whatever to spend a portion of your time not just doing work, but ensuring you can continue to deliver value in the future.

Here's a metaphor for you:

Some people like 'release based' branching; because you can push all your changes into develop (however messed up they are), and then some poor soul has to someone pull out a release candidate and then slave away over it to make sure it works...

You release seldom... but, most developers don't have to worry about it (just the release manager), and its fine.

Some people prefer trunk based development; it's harder.

Every merge to master you have to make sure your code actually works, because hey, it might go live in the next 2 hours.

A lot of people really hate this, because it means they have to do a lot of work and they cannot push the hard work onto someone else.

...do you see the metaphor?

I think it's pretty relevant.

Address technical debt slowly and continuously, not rarely and massively, and you will, in my opinion and experience, have better outcomes.

This is still making a spectacular number of assumptions about other people's work environments. The technical debt they're dealing with may not even have been theirs in the first place, it could be an external codebase. It could be a dependency that's long since abandoned and is now a security risk. It could be that the project is deployed against a really old DB and the feature requested needs that upgrading. It could be any one of an almost infinite number of things that none of your scenarios seem to be aware of.
> Instead, say: this is how long it will take to do.

You'd better have Nostradamus-level prediction accuracy if you're going to play chicken like that with every estimate you're pressured to give.

> Doing a rubbish job as quickly as you can is not your job. Not ever.

Unfortunately someone else IS willing to do a rubbish job as quickly as they can, look absolutely golden to their managers and clients for a while, then slingshot their career on to the next big pay raise, leaving the next poor chump to take the fall for their malfeasance.

> You can't tell people; here is a dial, you can pick 'fast and you're screwed later' or 'slow and careful now'. You're setting yourself up for failure; they cannot pick 'slow and careful', because that's not their job; their job is to quickly deliver value/outcomes/whatever.

That sounds a little crazy. If you applied this same argument to money, you'd conclude that their job is to spend money as fast as possible in order to deliver value, and the debt that builds up is accounting's problem, not theirs. No successful business works like this, so clearly the logic does work if it's presented correctly.

The Agile process that companies insist on using includes technical debt as part of the deal. It's impossible to write software with constantly changing requirements, that you have no idea about more than 2 weeks ahead, and not incur technical debt. I would guess that nearly all technical debt is due to this, and not due to developers rushing.
Unfortunately it does not work in reality. There will be another guy who is ready to do "fast and dirty", and he will be give the responsibility and probably will lead the team in future.
Guess it depends on your management.

I've often told my boss the feature would be easy, but I would also like to take the time to clean up the code in the affected area since it's making it harder than it should be to implement changes. And I've gotten some time extra to do just that.

Other times I say doing it fast and cheap is possible, but I see an opportunity here to do something more clever and involved which will very likely open up further possibilities down the line. For example, I might predict other clients will need a similar feature, so by making my code a bit more general it should be easier to implement if they come asking for their variant.

Sometimes I get a green light on that, sometimes I do not.

I guess it helps that the owners are playing the long game, so my boss can afford to see beyond the next quarter.

even if you were to be "slow and careful" that doesn't garuntee you'll be on schedule, it could turn out later part of your architecture is not suitable for an area maybe due to requirements changing.

maybe you'll say, "requirements cant change!" on top of the earlier "deadlines should be reasonable!". IMHO that's fantasy, I've never worked on something where both these were true for 100% of a project

Controversial or not I agree 100%. You are a steward of the system. The hard part is to define “system” broadly enough to include an outlook that is at least medium term (relative to individual features) but not so broad that you kid yourself that you should be second-guessing things beyond your competence. Somewhere in that range is a sweet spot where a healthy negotiation could go either way, depending on circumstance and opportunity.
This is the "just don't have technical debt" argument. Which entirely misses the point.
I think permanency and maintainability are features too. I would be fine with telling corporate that we can build something, but it will collapse in 3 months and need a total rebuild.

If their budget allows for that, then okay we go ahead.

While I agree with this idealistic view, all it takes is one delusional, misinformed or ambitious EM to break rank and start cutting corners for short term wins with the management and before you know it all teams are now expected to do the same.

Any organization where management does not readily acknowledge their reliance on technology and its associated upkeep costs is doomed to eventually sink waist deep in a tech mud pool of their own making.

"Cheap, Fast, Good - pick any two"