Hacker News new | ask | show | jobs
by tonyjstark 1554 days ago
While the article delivers nice explanations for what kind of technical dept exist, it stays very generic and hand-wavy for the solutions. Bringing "microservices" into the room is definitely not helpful. Ownership and setting a quality bar..., sure but how does that look like? As I developer I maybe have an idea but I also need to sell that to management. As manager I have an idea too but I need to convince my developers to strive for quality and sustainability.

Sometimes I wish these articles would just state: Stop sprinting

Also: document your decisions! If you have to write down and justify your (prudent) technical dept, you maybe catch some stuff before it's written in code. It also makes sure more people are aware of it. Additionally, it sometimes prevents CV driven development, which imho is a big problem in tech. Overall, documentation is a very underused tool.

Finally: teach everyone (especially marketing) that software development is expensive, so everybody thinks twice before wishing for nice to have features done quick.

4 comments

Could not agree more. The solution to tech debt is the one nobody wants to hear: Slow down!

Steve Jobs' presentation of Snow Leopard should be mandatory viewing for every manager. "No new features" to a standing ovation. Customers actually like stable, responsive, and efficient tools, who would have thought?

EDIT:

> Bringing "microservices" into the room is definitely not helpful

It's a pretty good way to increase technical debt. The microservices themselves might become small enough that it is easy to refactor some at a time, but then you have the actual deployment and communication infrastructure to contend with. And if you get that architecture wrong, oh boy you'll be begging to go back to a monolith in a day.

> It's a pretty good way to increase technical debt. The microservices themselves might become small enough that it is easy to refactor some at a time, but then you have the actual deployment and communication infrastructure to contend with. And if you get that architecture wrong, oh boy you'll be begging to go back to a monolith in a day.

I remember at a previous job, the monolith was drowning in technical debt. Someone decided the solution was Go microservices. Fast-forward 18 months and 95% of the functionality is still in the monolith, but there are now 25 microservices, and no environment (except production) where you can test everything together.

> I remember at a previous job, the monolith was drowning in technical debt. Someone decided the solution was Go microservices. Fast-forward 18 months and 95% of the functionality is still in the monolith, but there are now 25 microservices, and no environment (except production) where you can test everything together.

I have the opposite anecdote. Currently working on a monolith that's been around for 5-7 years, huge enterprise Java mess, like many others in the industry. The clients decided that they'd like to upgrade to JDK 11, newer frameworks, all of that shiny stuff.

So for the past 4 months i've essentially been pulling my hair out and trying to rewrite significant parts of it all. When you have a monolith, you cannot upgrade the entire system if some parts of it break - even if i have, say, 200 dependencies but 10 break, i cannot move forwards with the updates and as a consequence am stuck with running on JDK 8 or even outdated frameworks.

And, of course, you cannot extract those parts of the system out either because you'll immediately be hounded by developers who aren't welcoming of change and will find nitpicky stuff to tear both your arguments and efforts apart, actively sabotaging any potential successful outcome (potentially exaggerating here, but many do not enjoy change).

Alas, there is probably some sweet spot to work towards from day 1. Not going crazy with microservices, especially due to how people interpret the "micro" part (e.g. service per person vs service per team, what the total count should be, domain modeling etc.), but not sticking to a single large monolith either.

I think that sooner or later the industry will try grouping code into services based on the "type" of functionality - the weird PDF export and reporting logic will live in service A, other attachment upload/download logic in service B, the web API in service C, and the old legacy server side rendered UI in service D. That way, at least your efforts to update the web framework and JDK for it wouldn't be usurped by the PDF library not liking it.

Then again, i've seen front end applications baked into back end applications instead of separate back end/front end deployments far too often, so i'm not hopeful about anyone genuinely exploring that approach anytime soon.

Alternatively, i've actually written about modular monoliths before, in my article "Moduliths: because we need to scale, but we also cannot afford microservices": https://blog.kronis.dev/articles/modulith-because-we-need-to...

I don't disagree - this mononlith was running on three to four year old dependencies, and on the rare occasion that someone did make any big updates it was a case of hoping that the tests passed and then hoping that nothing broke in production.

But it wasn't broken up because it was too hard to update dependencies, it was broken up because it was a complicated mess. They just traded it off for another complicated mess.

Coinbase?
Snow Leopard is exactly what I had in mind when writing the comment. I remember watching the keynote and my own excitement about introducing no new features.

Additionally to managers watching that presentation, software architects should mandatory have to work as normal developers in every project they designed for a a few months. Best, if it would be around 2 years after they came up with the architecture. If you don't taste what you cook, how can you learn?

I fully agree on your points with microservices.

This happens constantly, the entire tech industry runs in whatever direction Google in particular is going. First it was Hadoop and all the pain that came with that, and now it's microservices and kubernetes and all the shit that brings into our tech stacks.

Stop sprinting is good but also : stop following Google. You are not Google. You do not have the needs of Google. Just stop it.

Pick the simplest tech stack you can find. This gives 100x more time to your developers to work on company solutions and not fighting technical complexity.

Pick the simplest tech stack you can find.

There is a lot of merit in that argument.

It never ceases to amaze me how much effort we now spend on nothing but infrastructure and architecture. It's like the Cloud Way of "cattle not pets" and "infinite horizontal scalability" may no longer be questioned.

Meanwhile you could build almost anything in this space with little more than a rack of real servers, some respectable application code written in a fast language, and a bit of scripting and OSS for the glue.

Obviously that sort of environment wouldn't be sufficient for every modern, online-first application but how many years would it take to outgrow it? Many applications never reach that scale. The lucky few would be in a great position to expand from if their starting point was simple and transparent with minimal dependencies.

> now it's microservices and kubernetes and all the shit that brings into our tech stacks.

For all the talk about "no silver bullet", there's a staggering amount of folks who keep falling for it.

The problem is you eventually need the things k8s offers and you end up implementing part of k8s, badly. I've seen bigish places that state "we aren't Google" as an argument to not use k8s, containers, etc but don't consider that their tech stacks are a Hodge Podge of bespoke glue, a mass of technical debt and a bus factor of generally 1 or 2.
The question they should be asking isn't "is this tech stack perfect or a mess" it's "is this actively preventing, or about to prevent, us from meeting our uptime and cost and development goals"?

The idea that a shop that built a messy system will suddenly build a non-messy system just if they pick up a new set of tools - that they don't have practice with anyway! - is exactly the silver-bullet fallacy. The system turned out messy because it's complicated, switching to a very complicated tool doesn't take away the complexity, it just changes the way you manage it.

The last couple Kubernetes shops I worked at were that exact sort of hodge podge of custom glue with high tech debt and low bus factor. Just even doing something "simple" like "ssh into the box and poke around" when the two wizards are out suddenly has a huge learning curve. ;) So then you get into discussions of "oh you should've been using managed kube" or "oh, don't use TF -> helm -> kube, use [other way] of managing it" or blah blah.

After you fuck it up a few time you might have enough useful experience so that you can build it well next time... just pray that by then we're still using the same tools. :D

There is a huge learning curve with k8s and there really needs to be a "k8s the good parts" for tooling to use. The problem with k8s vs $custom_system is k8s is somewhat well thought out and $custom_system is generally not.
As someone who works on a hodge podge of bespoke glue, a mass of technical debt, a bus factor of 1, and a docker swarm setup, I don't really see how k8s would help ;)
> Customers actually like stable, responsive, and efficient tools, who would have thought?

_Existing_ customers like these things (and they aren't wrong for liking these things).

New business comes from the potential customers who weren't enticed by the existing feature set, robust or otherwise. You bring them in by adding new features. The retain/new business priority is often heavily weighted in favor of the latter.

Retaining existing customers stuck with a crappy product ain't that hard between sunk cost/lock-in effects and the evergreen insulation of people with purchasing authority from the day-to-day pain inflicted by their purchasing decisions. A couple fancy steak dinners for middle management effectively papers over the cost of driving a department of ops engineers to cirrhosis several times over.

You're absolutely right, and it makes me sad :(
Slowing down is really being able to say "no" to features for awhile while you re-architect the codebase - so you're delivering stuff at the same pace, but that stuff is not product-facing.

I've been through this slog - sometimes it requires fixing what's there and other times, a rewrite. People hate rewrites, but it really is the best way forward in a lot of cases if done correctly.

+10

This is my experience with many different systems. I’ve found that mentoring and personal development identification techniques for what to learn, and when, can be helpful. Inviting a developer to be part of the decisions made regarding their future may seem obvious, but in practice it’s often not done…

And documentation… I’m known as “Just write it down,” but there is usually significant pushback… from all parties.

> hand-wavy for the solutions

This is Fowler (and Uncle Bob's) stock in trade tbh.

Generic good advice that sounds plausible in a sane world.

Without ever acknowledging that we actually don't live in that world.

If only the author had written a book about how to alter crappy code to make it better. Then maybe he could give us a plan!