Living with technical debt - the unwanted roomate

cityexpert Cityexpert

Congratulations! Your startup has just landed a dream investment, you have a working MVP and the  product is getting some traction. The next thing you are expected to do is take the whole business to the next level… scaleup and expand. This requires major transformation of the entire company including your code. However, one thing slowing you down in this endeavor is technical debt. So in this post I'll try to cover some of the key takeaways and practices we have learned in making City Expert the company it is today. First thing's first, let's start with setting up your expectations.

Can I have zero technical debt?

We've all heard the stories of failed startups that have accrued so much technical debt that they collapsed on themselves and never recovered. Naturally, one might think: "Hey this won't happen to us. We'll be smart when it comes to our product architecture and lay ground for the possible features we might make one day. We’ll take our time and have a solid foundation."

That, however, is naïve thinking in several ways. Firstly, you will not be able to predict the future requirements your product will have. You might be fully aware of some and prepare for them, but sooner or later an unexpected business requirement will pop up and an architecture decision from a year ago will come back to haunt you. Secondly, there is never 'taking our time'. After you refine your vision, you start throwing a pile of technologies and codes to have a working proof of concept for validation as soon as possible. Then if you see potential, you'll want to get some investments going. By the time you get your first investment it is too late since the next thing you are to do is scale and that, justifiably, was never a top priority… until now.

How do I manage the creation of technical debt?

So moving fast does not work since it creates unreasonable technical debt and moving slow is not business viable and can leave your project in development hell. The solution I propose is making a compromise and never forgetting you are making it. The compromise is the following: for each bad architecture decision you give in to, you DO NOT give in the next one. For the ones you do give into you write clear comments in the code (if applicable) and make tasks for fixing them in the future with a plan on when you will them tackle them. This will greatly reduce the amount of technical debt going into the project.

When am I going to pay the debt?

Technical debt fixes tends to get postponed quite often and easily. Most of it comes with the justification: "We've lived with this for all this time, we'll manage for a few more months". Temporary code becomes permanent almost unnoticeably. So how to deal with this? Well the first rule is: be reasonable. Some temporary fixes will become rather permanent, since more important do or die work and features will come up and nothing can be done about it.

The second rule is: use technical debt as a bargaining chip. A business requirement will come up that needs to be addressed ASAP and you will say: sure, but after that we must delegate time to fix the mess a previous instant feature created. One comes in, one goes out and the technical debt level stays stable.

Can any part of the project be moved to technical debt?

The one place where you should never play around with technical debt is when you are setting up your infrastructure. This includes the setup of the possible frameworks and libraries you are using, setup of the build and deploy pipeline, setup of the testing infrastructure, setup of the telemetry acquisition system and setup of the storage infrastructure. I listed the ones I find essential for City Expert however your startup very well may differ in terms of infrastructure.

When setting all of these up you must answer (or better yet, prepare for) the question: How will this work when we scale up? Without going into detail why each and every one of these infrastructure parts I find essential, having them work without a hitch will greatly reduce the time a bug is getting solved, reduce the severity of most technical debt you have to introduce, will protect you against unrecoverable data loss and increase the confidence in your projects code.

The ugly truth is: technical debt will always be present in the startup world, you just need to learn how to live with it.

Stefan Pekić
Chief Technical Officer