Daftar utang adalah spreadsheet sederhana atau epic Jira yang mencantumkan item technical debt yang diketahui beserta perkiraan upaya remediasi dan dampaknya terhadap kecepatan pengembangan jika dibiarkan. Post ini merekomendasikan peninjauan setiap kuartal. Disiplin menuliskannya memaksa tim untuk mengungkapkan biaya nyata setiap item — yang sering kali mengungkapkan bahwa sebagian 'utang' sebenarnya hanya kode yang tidak disukai, bukan kode yang benar-benar memperlambat pengiriman.
Post ini merekomendasikan alokasi 15–20% dari setiap sprint secara eksplisit untuk pengurangan utang — bukan sebagai waktu sisa, melainkan kapasitas yang dianggarkan di muka. Ini mengikuti rekomendasi McKinsey untuk pengurangan utang yang sistematis. Tanpa anggaran eksplisit, pekerjaan fitur selalu terasa lebih mendesak dan pengurangan utang tidak pernah terjadi. Keuntungan produktivitas dari pengurangan utang biasanya balik modal dalam 2–3 bulan melalui pengiriman fitur yang lebih cepat dan lebih sedikit bug.
Ketika developer menulis ulang sebuah modul tanpa tes yang mencakup perilaku yang ada, hasilnya mungkin terlihat lebih bersih tetapi bisa memperkenalkan regresi perilaku halus yang baru muncul di lingkungan produksi. Post ini mewajibkan penulisan tes karakterisasi terlebih dahulu — tes yang mendokumentasikan apa yang dilakukan kode lama — menjalankannya pada kode lama, lalu merefaktor hingga tes yang sama lulus pada kode baru. Ini adalah satu-satunya jalur aman untuk kode warisan yang belum memiliki tes.
Post ini merekomendasikan kerangka dua sumbu berdasarkan dampak (seberapa besar utang memperlambat pekerjaan saat ini dan yang direncanakan) dan biaya remediasi (berapa lama waktu perbaikannya). Hasilnya adalah matriks 2x2: dampak tinggi dan biaya rendah dikerjakan sprint berikutnya; dampak tinggi dan biaya tinggi dijadwalkan sebagai proyek; dampak rendah dan biaya rendah diperbaiki secara oportunistik; serta dampak rendah dan biaya tinggi cukup didokumentasikan dan diterima.
Post ini menerapkan sudut pandang ekonomi: jika biaya remediasi tidak akan terbayar dari waktu yang dihemat sebelum kode tersebut diganti atau dihapus, lebih baik dokumentasikan dan biarkan. Modul yang stabil dan jarang disentuh dengan tes komprehensif boleh dibiarkan meski gaya kodenya sudah tua, dan layanan backend yang dijadwalkan diganti dalam enam bulan tidak perlu refaktor besar. Utang pada kode yang akan dihapus paling baik dikelola dengan menghapusnya lebih cepat, bukan membersihkannya terlebih dahulu.
McKinsey menemukan bahwa technical debt menyumbang 40% dari neraca IT, dan perusahaan dengan rasio utang tertinggi mengalami pertumbuhan pendapatan 20% lebih rendah daripada yang memiliki utang yang dikelola. Developer menghabiskan 33% waktu mereka pada technical debt — memelihara kode lama, men-debug sistem kuno, dan merefaktor jalan pintas yang masuk akal tiga tahun lalu tetapi sekarang memperlambat segalanya. Panduan ini adalah pendekatan praktis saya — kerangka yang sama yang saya gunakan ketika mewarisi codebase atau meninjau arsitektur sistem yang telah tumbuh melampaui desain aslinya.
Ward Cunningham menciptakan metafora technical debt pada tahun 1992: memilih implementasi yang lebih sederhana sekarang menciptakan utang yang harus dibayar kemudian (dengan bunga). Seperti utang keuangan, beberapa technical debt bersifat strategis — Anda sengaja mengambil jalan pintas untuk mengapalkan lebih cepat, dengan rencana untuk merefaktor kemudian. Utang yang ceroboh adalah masalahnya — jalan pintas yang diambil tanpa kesadaran yang menciptakan biaya pemeliharaan yang berkelanjutan.
Utang hadir dalam beberapa bentuk: Utang kode (logika spaghetti, tes yang hilang, kode yang disalin-tempel), Utang arsitektur (desain yang masuk akal untuk 1.000 pengguna tetapi rusak pada 100.000), Utang dependensi (pustaka yang sudah usang dengan kerentanan yang diketahui), Utang dokumentasi (kode yang berfungsi tetapi tidak ada yang tahu bagaimana atau mengapa), dan Utang operasional (proses manual yang bisa diotomatiskan).
Technical Debt Prioritization Matrix
REMEDIATION COST
Low High
┌───────────────┬───────────────────┐
IMPACT High │ DO NEXT │ SCHEDULE AS │
│ SPRINT │ A PROJECT │
│ │ │
│ e.g. missing │ e.g. full service │
│ index causing │ rewrite that's │
│ 5s query → │ blocking 3 │
│ fix in 2hrs │ quarters of work │
├───────────────┼───────────────────┤
Low │ FIX │ ACCEPT & │
│ OPPORTUNIS- │ DOCUMENT │
│ TICALLY │ │
│ │ │
│ e.g. rename │ e.g. old util │
│ confusing │ nobody touches │
│ variable │ but costs 3wks │
│ │ to rewrite │
└───────────────┴───────────────────┘
Sprint Budget Allocation:
─────────────────────────
Feature work: 80%
Debt reduction: 15% ← Always in sprint, not optional
Unplanned/bugs: 5%
Quarterly Debt Sprint: Full sprint dedicated to matrix quadrant 2Dari memelihara codebase ERP Commsult: buat 'daftar utang' — spreadsheet sederhana atau epic Jira yang mencantumkan item utang yang diketahui, perkiraan upaya remediasi, dan perkiraan dampak pada kecepatan pengembangan jika tidak ditangani. Tinjau setiap kuartal. Ini mengubah utang yang tidak terlihat menjadi pekerjaan yang terlihat dan dapat diprioritaskan.
Utang itu mahal dalam tiga cara: (1) pelambatan — fitur yang menyentuh kode berat utang membutuhkan 2-3x lebih lama untuk diimplementasikan dan diuji; (2) amplifikasi cacat — kode yang rapuh menghasilkan lebih banyak cacat per fitur; (3) gesekan developer — insinyur yang menghabiskan hari-hari mereka melawan kode lama kelelahan dan pergi.
# Technical Debt Register (debt-register.md)
## High Impact / Low Cost — Next Sprint
| ID | Description | Owner | Effort | Impact |
|-------|-------------------------------------|---------|--------|--------|
| TD-01 | Missing index on invoices.tenant_id | @dev1 | 2h | -5s query |
| TD-02 | Copy-pasted email templates (×5) | @dev2 | 4h | Maintainability |
| TD-03 | Hardcoded config values in service | @dev1 | 3h | Env parity |
## High Impact / High Cost — Scheduled (Q3)
| ID | Description | Epic | Effort | Impact |
|-------|-------------------------------------|---------|--------|--------|
| TD-10 | Migrate approval workflow to CQRS | EP-42 | 3wk | Scalability |
| TD-11 | Replace hand-rolled auth with JWT | EP-43 | 2wk | Security |
## Low Impact / Low Cost — Fix Opportunistically
| ID | Description | Note |
|-------|-------------------------------------|-----------------------|
| TD-20 | Rename confusing 'data' variables | Fix when in that file |
| TD-21 | Add missing JSDoc to public APIs | Pair with new feature |
# Characterization Tests Before Refactoring
# Run on OLD code first — verify they pass. Then refactor.
describe('ApprovalWorkflow (characterization)', () => {
it('allows manager approval on level 2+ invoices', async () => {
// Document existing behavior exactly — good or bad
const result = await workflow.canApprove('manager', level2Invoice);
expect(result).toBe(true); // whatever it currently returns
});
});Alokasikan 15-20% dari setiap sprint untuk pengurangan utang — bukan sebagai waktu sisa, tetapi sebagai kapasitas eksplisit yang dianggarkan di muka. Ini adalah alokasi yang direkomendasikan McKinsey untuk pengurangan utang yang sistematis. Tanpa alokasi eksplisit, pekerjaan utang tidak pernah terjadi karena fitur selalu terasa lebih mendesak.
Pola technical debt yang paling berbahaya: developer menulis ulang modul 'untuk membersihkannya' tanpa tes yang mencakup perilaku yang ada. Penulisan ulang mungkin terlihat lebih bersih tetapi memperkenalkan regresi perilaku halus yang hanya muncul dalam produksi. Sebelum merefaktor modul signifikan apa pun, tulis tes karakterisasi terlebih dahulu — tes yang mendokumentasikan apa yang dilakukan kode yang ada.
Tidak semua utang itu sama. Prioritaskan berdasarkan dua dimensi: (1) Dampak — seberapa besar utang ini memperlambat pekerjaan saat ini dan yang direncanakan? (2) Biaya remediasi — berapa lama untuk memperbaiki ini? Gunakan matriks 2x2: dampak tinggi + biaya rendah → lakukan sprint berikutnya; dampak tinggi + biaya tinggi → jadwalkan sebagai proyek; dampak rendah + biaya rendah → perbaiki secara oportunistik; dampak rendah + biaya tinggi → terima dan dokumentasikan.
Pengurangan utang gagal ketika diperlakukan sebagai proyek khusus yang terjadi 'ketika ada waktu' — yang tidak pernah. Jadikan berkelanjutan: sertakan dalam kapasitas sprint (aturan 20%). Berikan insinyur otonomi untuk memperbaiki item utang kecil secara oportunistik ketika mereka berada dalam sebuah file (Aturan Pramuka: tinggalkan kode lebih bersih dari yang Anda temukan). Rayakan kemenangan pengurangan utang dalam retrospeksi.
Tidak semua utang perlu dibayar. Modul yang stabil dan jarang disentuh dengan tes komprehensif baik dibiarkan apa adanya bahkan jika gaya kodenya sudah tua. Layanan backend yang dijadwalkan untuk diganti dalam enam bulan tidak memerlukan refaktor besar. Utang dalam kode yang akan dihapus paling baik dikelola dengan menghapusnya lebih cepat, bukan membersihkannya terlebih dahulu.