I meet a lot of companies when things have gotten difficult for them. Very often, it's because they've amassed a lot of technical debt, and now it's being called in.
"Technical Debt," quite simply, is everything technical that wasn't done right, plus everything that wasn't done at all. Code without test coverage, code without documentation, one-off functions to meet a particular need, lack of monitoring, architecture that prevents scaling, and much, much more. Honestly, there's nothing wrong with technical debt in itself. Young, scrappy startups usually have no choice to build up a lot as they build their MVP. (Deferring these tasks is a big part of the "minimal" in minimally viable product.)
Where technical debt comes back to haunt people is when they don't account for the actual dollar figure that the debt represents. Even worse, most startups don't even know what that figure is. When it catches up to them, it can be really painful.
The first pain point is the "interest" on the debt. As time goes on, this debt-ridden code base becomes harder to maintain. A new feature which should have taken 4 hours to implement now takes 6, because the coder has to spend more time figuring out how to implement the feature, and then check to make sure it hasn't broken something. The 6 hours really turns into 12, because the code did break something - something far away in the code that isn't noticed until it's in production. Just like compound interest, this adds up quickly. Pretty soon, your progress begins to slow to a crawl, usually right about the time you need to show traction and growth to your next stage investors. (Side note: are you raising enough to pay off the technical debt you've accumulated?)
The other pain point comes when the technical debt becomes suddenly due: for example when your developer (your friend's roommate's cousin who just graduated from some 24 week code school) gets a new gig. Now, everything takes 5 times longer and costs 10 times more, because someone has to puzzle out where in the spaghetti mess of the MVP a particular function lies. No matter how many times you replace your new developer, the results will be the same, because no one can make a good omelet from rotten eggs. Or perhaps you get upvoted on ProductHunt without warning, and you need to scale up to multiple servers, only to learn that your app is running on Heroku and storing critical files on the local instance. Now, you're completely screwed, because you didn't build to scale and there's no time to react before people have a bad experience and you're downvoted to oblivion.
Too many viable companies die, bankrupt from technical debt, when it is completely unnecessary. Want to avoid their fate? Before you write a single line of code, know what the best practices and "right" way are, then each and every time you depart from them, document why and assign a dollar value of technical debt. Accumulating debt isn't a problem as long as you manage it and stay ahead of it. Before you start, or, if you've already started, stop and do these things:
- Architect for your BHAG. Imagine what is necessary to run your amazing new idea at scale with the maximum number of users you might have. Your CEO is probably off pitching that bullshit "if we capture just 1% of this market" line. Design your technology so that you can handle 5% of it. Yes, setting up an auto-scaling AWS infrastructure is harder than Heroku or deploying on some one-off VM. But it's not that much harder. (At least not now. It's pretty hard when you're site is down from the load and your CEO is screaming and your (potential) investors are shaking their heads.)
- Use a source code repository, and take advantage of the settings that keep you honest:
- Do everything as pull requests and document what each PR is doing.
- Use branch protection to prohibit merges to your master branch unless your code passes tests and and code review.
- If there are two of you who are even mildly technically literate, review each other's code. You don't have to review for best practices, just review for "can I tell what this code does?"
- Use a code review tool and obey it! If the tool is blocking a merge, don't turn off the test, but instead skip the offending code with an inline directive and record this as technical debt.
- Write tests. Use a continuous integration tool to run the tests before a merge. At the absolute minimum write a pending test placeholder and record this as technical debt. Use the CI tool to report the percentage of test coverage. What's your test debt? It's roughly the reciprocal of our coverage multiplied by total development hours. (For example, 88% coverage after one month of full-time development: 0.12 * 173 = 21 hours. 21 * $75 = $1,575 of real, genuine debt you will need to pay back someday.)
- Use a tool like Pivotal Tracker or Trello so that those who come later can see what you did and why. Document your decisions. Watching your velocity slow down on Pivotal Tracker as you accumulate debt should also be a warning and indicator of coming trouble.
- Get outside advice regularly. Find someone who will look at your architecture and all your code metrics, and warn you if they see problems.
As with every other risk to your business, manage your technical debt well. The company you save may be your own.