Technical Debt
Technical debt is like a loan. You take a shortcut to gain speed now, and you pay later through slower changes and more bugs. A small, planned shortcut can be a useful tool. A shortcut taken blindly, never fixed, and left to grow makes the codebase hard to change. Take shortcuts on purpose, write them down, and pay them back.
Not all debt is equal. Planned, sensible debt is a fair trade-off, for example: "we will ship the simple version now and improve it after launch." This works when you decide it on purpose and record it. Careless or accidental debt is a mess made through haste or lack of knowledge. It has all the cost and none of the benefit. The skill is to tell them apart, choose debt on purpose, and never pretend a shortcut is free.
One line must never be crossed: security and compliance are not negotiable. Cutting a corner on a fail-closed check, tenant isolation, or an audit trail is not debt you can repay later. It is shipping a vulnerability. It is fine to make speed-versus-quality trade-offs openly. It is never fine to weaken a control quietly to hit a date.
Borrow deliberately
- DoMake shortcuts deliberate decisions. State the trade-off, the benefit, and the cost, and get agreement rather than deciding alone.
- DoRecord debt where people can see it: a tracked ticket, a TODO with context, or an ADR. Make it a known item, not a hidden surprise.
- DoLeave code a little better than you found it. Small, steady improvements stop debt from building up.
- ConsiderSetting aside regular time to fix the most costly debt: the code you change often and that slows the team most. Do not only add features.
- Do notTake on debt by being careless. Accidental mess has all the cost of debt and none of the benefit.
- AlwaysRaise a quality trade-off openly and make it an owned decision. Never decide it quietly.
Keep debt on the right side of the line
- DoFix the most costly debt first: the debt that slows changes, causes repeated bugs, or adds risk. Do not just fix what is annoying.
- DoTreat old debt as risk on a regulated platform. Fragile, poorly understood code around money or compliance is a hazard, not just untidy code.
- ConsiderImproving the code as you work in an area, rather than waiting for a large rewrite that never happens.
- Do notLet debt build up quietly until the codebase is too fragile to change safely. That is the outcome you are avoiding.
- NeverTake on "debt" by weakening a security or compliance control. A skipped fail-closed check, missing tenant scope, or absent audit trail is a vulnerability, not a shortcut.
// temporarily skip the screening check to hit the demo deadline
// catch { /* ignore */ } then approve anyway
This is not a shortcut to repay later. It is a fail-open AML control that approves customers with no screening. You must raise it and refuse it, not record it as 'tech debt'.
// TODO(JIRA-1234): MVP uses a synchronous call to the report builder.
// Acceptable for launch volumes; move to a background job before we
// onboard tenants over ~10k customers. Owner: payments team.
A deliberate trade-off with a reason, a limit, a ticket, and an owner. This is debt used as a tool: visible and repayable.
Self-review checklist
- AskIs this shortcut a deliberate, recorded trade-off, or accidental mess I am pretending is fine?
- AskHave I written down the debt, with its cost and an owner, so it is visible?
- AskDoes this cut a corner on security, tenant isolation, or compliance? If so, it is not debt. Stop.
- AskIs the most costly debt, the debt that slows us most, actually getting fixed?