Software Architect · Module 03
Technical debt isn't a synonym for bad code. It's a compromise that has to be deliberate, written down, and eventually paid back.
Debt quadrant · interest · repayment strategy
Debt is useful when it buys time. Debt is dangerous when the team doesn't know it took out a loan.
Not every piece of bad code is debt
A loan and a stolen wallet both create a financial problem. They have to be managed in different ways.
Technical debt appears when the team consciously chooses a cheaper-now solution while understanding the future cost. For example: "We're not building a full multi-tenant model until we have paying customers." That's debt.
But "we didn't write tests because we forgot" or "nobody understood the invariants" — that isn't debt, it's a defect of engineering discipline. Calling everything debt is dangerous: the business stops being able to tell where a strategic compromise ends and bad work begins.
The interest matters more than the principal
A small pothole right next to your house annoys you every day. A big pothole deep in the forest can sit there for years and bother no one.
The interest on the debt is the slowdown it imposes on changes. If the debt sits in the hot path of development, it's expensive even if the chunk is small. If it sits in a rarely-touched migration script, it may be tolerable.
The architect evaluates not just "how ugly is this" but "how often do we pay for it." That's why a debt register should carry impact, owner, trigger for repayment, and risk.
Debt becomes manageable when it has a reason and a repayment strategy.
Example: temporarily single-region
A new shop opens its first store first. It doesn't build national logistics before the first sale.
The team launches the SaaS in a single region even though they know enterprise customers will later demand data residency. The decision is captured in an ADR: single region for now because we have no customers with that requirement; revisit on the first enterprise contract or when 20% of users come from the EU.
That's reasonable deliberate debt. It has a reason, boundaries, and a trigger for revisiting.
"We'll rewrite it later," with no date and no condition, isn't a plan. It's an incantation.
The team writes billing without idempotency because "user volume is still low." That's dangerous: one mistake can cost money and trust immediately. That debt is unreasonable, because the risk is disproportionate to the saving.
Not all debt is equal. Debt in payments, security, data, and legally significant actions requires a much harder justification.
- Why did we take this debt on? - Who owns paying it back? - What signal will make us return to it? - Which users get hurt if the debt fires?