Technical Debt and The Planning Fallacy
If you ask me how long it will take to do a familiar but substantial task, chances are I’ll give you a wrong answer. I will tell you, “That will take me two days,” when in fact it has never taken me two days. Perhaps it has always taken at least three, and usually four. But I’m unable to think accurately enough about the past to reach this conclusion, especially if you ask me directly. This is a rough explanation of the Planning Fallacy, one of the most fascinating and pervasive cognitive biases. We all suffer from it when we make estimates, and it is especially acute with off-the-cuff estimates intended for an audience. We feel the pressure of judgment on our estimates, and unconsciously seek approval by providing optimistic and incorrect numbers.
Hofstadter’s Law formulates the cognitive puzzle embedded in this fallacy:
It always takes longer than you expect, even when you take into account Hofstadter’s Law.
Knowing about the Planning Fallacy isn’t enough to escape its influence.
Multiply this estimation inaccuracy by a large number—a factor determined by the complexity of the project—and this accounts for the primary reason that most projects fail to deliver on time. The “padding” that individuals, their managers, and their managers’ managers regularly add to work estimates is often whittled away during the piecemeal negotiation that falls between the estimation and commitment phases, leaving the original, overly optimistic estimates.
The bottom line is, and always has been, that estimates we make at the beginning of a project, because they are made in ignorance of the future, and because the Planning Fallacy distorts our thinking, all too often range from Pollyannaish to tragically mistaken. See Jim Benson’s Why Plans Fail for a concise and revelatory spelunking into the depths of the planning mind.
When we allow a project to be bound by our initial estimates, whether they were constructed with the best of intentions but subject to the Planning Fallacy, hampered by a misunderstanding of the requirements, distorted to meet the demands of the client, or simply doomed to irrelevance by the inevitable array of exigencies that befall every project, we force reality into an inappropriate container.
But we still need to execute on the project plan, whatever its condition. Content strategy, UX, information architecture, conceptual design, applied design, rounds of approval and review: these initial phases may expand as they attempt to capture the entirety of emerging requirements, and subsequent phases become necessarily further compressed.
The technology team deals with this compressed time frame by (a) being galactic geniuses (I am not biased) and (b) making compromises. Compromises can be deliberative and explicit, panicked and hidden, or half-heartedly considered and partially documented by inline code comments.
Some compromises are driven by a clear-eyed assessment of the border between Minimally Sufficient and Fancy. Although programmers are famously lazy, they are just as often driven (by Larry Wall’s #3, Hubris) to engineer the perfect solution where an adequate one is the optimal path. Choosing adequate over perfect means that we can reserve precious engineering time for the hairier tasks, or the unexpected but inevitable road bumps that put further pressure on development schedules: bugs in the platform or a crucial module, foibles of the programming language, unexpected complexity in meeting a functional requirement, iterations between UI design and software implementation, and so on.
We can expect road bumps, but we can’t plan for them. If we start a development cycle with an unrealistic schedule estimate, then we can just expect to be late from the start. In an atmosphere like this, ill-considered compromises are almost inevitable. These compromises constitute the primary source of technical debt introduced to a new code base. We can only hope that the developers at least take the time to add TODO-style comments to mark the code they’d like to refactor in the future.
You can find these later:
$ find . -type f -exec grep -i todo {} \;
(Try that in Magento Enterprise 1.12’s app/code directory: 171 of them. It happens to the best of us.)
There are basically two strategies here:
- Minimize bad technical debt* and stress by renegotiating the release schedule
- Plan to address bad debt in a subsequent release
#1 is vastly preferable. #2 is only possible if you can isolate and track the debt, and push off developing new features in favor of addressing old problems. This often requires a heightened level of transparency between the technical and business teams. Otherwise, building new features on top of crufty, debt-ladened code will hinder progress on the features, slow your development velocity, increase the overall error rate, and reduce your ROI by alarming numbers.
How to minimize contact with this Planning-to-Debt problem: Plan to revise your estimates. Regardless of your project methodology and how it incorporates estimates, educate all project stakeholders as to the reality of estimation, if it’s not already abundantly clear. Help the team to understand that the process of estimation is more valuable than the estimates it produces.
* “Bad technical debt”: Not all technical debt is bad. Another useful distinction is short-term versus long-term debt.







