“Move fast and break things.”—Mark Zuckerberg
In fairness, as quotes go, that one is pretty excellent. It’s succinct, empowering, and motivating. It’s also desperately in need of a second sentence along the lines of, “Once it works, go back and do it correctly!”
Technical debt didn’t start with Zuck’s bold mission statement. He simply made a motto out of what most of us programmers have been doing since time immemorial. We build things, but more than that, we often have to invent the way we build them as we build them.
That’s a messy process.
Oftentimes, the problems we’re building solutions for are so large or complex that we’re writing code just to see if what we’re envisioning is even possible. This proof-of-concept stage is one of my favorite parts of programming. Prototyping an idea can be immensely satisfying, although is rarely well planned, and this is where the origin of most of our technical debt begins.
From Prototype to MVP
Development cycles move fast. For many reasons, the excitement around a working proof-of-concept can quickly become a sprint to a minimum viable product. Whether you’re trying to beat a competitor to market or think you’re onto the next big thing, it’s rare for developers to slow down at this point.
This makes sense. The world of development can be capricious and ephemeral, and speed does matter. It’s in this phase of the process that technical debt begins to really rack up. Quick-fix code solutions designed to get a feature up and running or to find a viable integration of outside data rarely hold up well once scaled.
Almost nobody lies to themselves as regularly or effectively as a programmer. While accruing technical debt, we intrinsically know we’re taking shortcuts, but we promise ourselves we’ll be back to fix this as we sail forward onto the next feature.
This creates an exponential chain reaction. As your project takes real shape, there is always another feature (or features) on the horizon. This isn’t a bad thing in and of itself; in fact, it’s usually a sign that what you’re working on has value, but as you leave each barely functional feature behind to start on the next one, your tech debt inches ever higher.
Technical Debt Charges Interest
Admittedly, it’s a bit of a cliche, but it’s also true. The longer you ignore that pile of tech debt, the larger it gets, but also the harder it gets to address. Undoubtedly, new features and functions have changed the landscape of your application, and figuring out how to wire everything back together becomes difficult.
Shoddy variable naming practices, insecure data access methods, buggy third-party libraries, etc. all begin to make that transformation from a molehill to a mountain. It’s not uncommon for application state to get buggy or UI issues to crop up at this point.
A Necessary Evil That Shouldn’t Be Ignored
In practical terms, technical debt is unavoidable. It’s a necessary evil empowering us to move quickly towards a better understanding of the big picture. Balancing when and how to address technical debt is a difficult decision that shifts from project to project.
But address it you must.
Ignored technical debt will wreak havoc as your project moves into launch. Under the strain of multiple concurrent users or unanticipated user workflows, the cracks will show. In the best of all worlds, this can be as minor as UI anomalies, but unaddressed technical debt can also expose user data. If your application tracks sensitive personal user information, this can be catastrophic.
Plan for the Fact You Didn’t Plan Enough
So what’s the right approach? Moving forward explicitly understanding that you perhaps haven’t planned out your project as fully as you’d like to is a good first step. In short, don’t lie to yourself.
- Take time after getting any feature working to make a couple notes on what needs to be addressed. Where are the shortcomings? What won’t scale well? Where are the fragile points? Even something as simple as having a running log will help hold you accountable for actually correcting those issues.
- Seek code review. Other developers can point out fragile points you might not recognize. Their experience can guide you in seeing the unexpected issues you may be creating along your way.
- Schedule refactor time. Build into your workflow time to go back and revise and optimize. You’ll always have something new to do, so if you don’t schedule time to address technical debt, you’ll likely ignore it.
Lastly, don’t despair. If you’re accruing technical debt, it probably means you’re building something cool and useful with room to grow. That’s an achievement; that’s why we do what we do!
Technical debt can cause real problems, but it’s not an 800-pound gorilla. It’s your code. You wrote it. Go fix it and make sure it performs the way you need it to, under all circumstances. Then go build that next great feature!