Mở đầu — vì sao bài này quan trọng
Hãy tưởng tượng bạn là PM của một startup fintech tại TP.HCM. Sáu tháng đầu, team của bạn ship tính năng nhanh như chớp: cho vay nhanh, ví điện tử, lịch sử giao dịch — tất cả lên production trong vài tuần. CEO hài lòng, nhà đầu tư gật gù. Nhưng đến tháng thứ bảy, mọi thứ chậm lại một cách kỳ lạ. Một tính năng nhỏ — thêm nút "lưu thẻ" — mà engineer ước tính tới ba tuần. Bug từ đâu kéo về liên tục. Mỗi lần release là một lần nín thở. Bạn hỏi tech lead "sao chậm vậy?", và câu trả lời chỉ gói gọn trong hai từ: technical debt.
Đây là khoảnh khắc mà rất nhiều Technical PM gặp phải nhưng không gọi tên được. Họ cảm nhận được sự chậm chạp, sự bực bội của engineer, sự sụt giảm velocity — nhưng không có ngôn ngữ để diễn đạt nó với cả engineer lẫn lãnh đạo. Kết quả: technical debt trở thành "vấn đề của engineering", PM đứng ngoài, và món nợ cứ lớn dần cho đến khi nó bóp nghẹt cả sản phẩm.
Là một Technical PM, bạn không cần viết code để trả nợ kỹ thuật. Nhưng bạn BẮT BUỘC phải hiểu nó là gì, đo lường được tác động của nó lên roadmap, và quan trọng nhất — biết cách trao đổi (communicate) về nó với ba nhóm đối tượng rất khác nhau: engineer, lãnh đạo kinh doanh, và chính khách hàng. Bài này dạy bạn đúng ba kỹ năng đó: hiểu bản chất, quản lý, và trao đổi.
Khái niệm cốt lõi
Định nghĩa gốc của Ward Cunningham
Năm 1992, Ward Cunningham — cha đẻ của wiki và một trong những người ký Tuyên ngôn Agile — đưa ra phép ẩn dụ kinh điển: "Shipping first-time code is like going into debt. A little debt speeds development so long as it is paid back promptly with a rewrite... The danger occurs when the debt is not repaid. Every minute spent on not-quite-right code counts as interest on that debt."
Tạm dịch: ship code lần đầu giống như đi vay nợ. Một chút nợ giúp bạn phát triển nhanh hơn — miễn là bạn trả nợ kịp thời bằng cách viết lại. Nguy hiểm nảy sinh khi món nợ không được trả. Mỗi phút làm việc trên đoạn code "chưa-thật-chuẩn" được tính như tiền lãi của món nợ đó.
Có hai ý quan trọng mà người ta hay hiểu sai. Thứ nhất, Cunningham KHÔNG nói technical debt là code dở hay code bug. Ông nói về khoảng cách giữa sự hiểu biết của bạn về vấn đề tại thời điểm viết code và sự hiểu biết đầy đủ hơn sau này. Thứ hai — và đây là điểm cốt tử — vay nợ một cách có chủ đích là HỢP LÝ, thậm chí khôn ngoan, nếu bạn có kế hoạch trả. Vấn đề chỉ xảy ra khi bạn vay mà không bao giờ trả, để lãi chồng lãi.
Lãi suất (interest) là gì trong technical debt
Đây là phần mà PM cần nắm rõ nhất, vì nó nối thẳng vào roadmap. "Lãi" của technical debt biểu hiện cụ thể qua:
- Velocity suy giảm: cùng một độ phức tạp, nhưng feature ngày càng tốn nhiều thời gian hơn để build.
- Bug rate tăng: mỗi thay đổi lại làm vỡ một thứ khác (regression).
- Onboarding chậm: engineer mới mất nhiều tuần mới dám đụng vào codebase.
- Khả năng dự đoán giảm: estimation ngày càng sai, khiến cam kết roadmap với lãnh đạo trở nên rủi ro.
Bốn loại technical debt — ma trận của Martin Fowler
Martin Fowler đề xuất một ma trận 2x2 cực kỳ hữu ích để PM phân loại nợ, dựa trên hai trục: chủ đích (deliberate vs inadvertent) và thận trọng (prudent vs reckless).
- Prudent + Deliberate (thận trọng, có chủ đích): "Chúng ta phải ship trước Tết, sẽ xử lý hệ quả sau." Đây là nợ tốt — vay có ý thức để đạt mục tiêu kinh doanh.
- Reckless + Deliberate (liều lĩnh, có chủ đích): "Không có thời gian cho thiết kế đâu." Vay vì lười, biết là sai mà vẫn làm.
- Prudent + Inadvertent (thận trọng, vô tình): "Giờ thì chúng ta mới biết lẽ ra nên thiết kế thế nào." Học được điều mới sau khi đã code — đây là loại Cunningham nói tới.
- Reckless + Inadvertent (liều lĩnh, vô tình): "Layering là gì vậy?" Team không đủ kỹ năng để biết mình đang tạo nợ.
Phân biệt technical debt với bug và với "code mình không thích"
PM hay nhầm. Bug là hành vi sai so với spec — phải sửa ngay. Technical debt là code chạy đúng nhưng cấu trúc khiến việc thay đổi trong tương lai tốn kém. "Code tôi không thích" hay "engineer mới muốn viết lại theo style của mình" thường KHÔNG phải debt — đó là sở thích. Là PM, bạn cần đẩy team trả lời: món nợ này khiến chúng ta chậm lại ở đâu, đo bằng con số nào? Nếu không trả lời được, có thể đó không phải debt thực sự.
Tình huống thực tế
Tình huống 1 — Tiki và món nợ "vay đúng lúc"
Bối cảnh: Một sàn thương mại điện tử lớn tại Việt Nam (gọi chung là sàn TMĐT để minh họa, lấy cảm hứng từ các campaign như 11/11, 12/12) chuẩn bị cho mùa sale lớn nhất năm. Team checkout phát hiện hệ thống tính phí vận chuyển hiện tại không scale nổi lượng đơn dự kiến tăng gấp 8 lần. Có hai lựa chọn: (a) viết lại module tính phí cho đúng chuẩn — mất 6 tuần, không kịp sale; (b) hard-code một bảng phí tạm thời cache sẵn cho 95% tuyến phổ biến — mất 4 ngày, kịp sale nhưng tạo nợ.
Diễn giải: PM quyết định chọn (b) — đây là nợ Prudent + Deliberate. Nhưng điểm quan trọng là PM không dừng ở đó. Họ tạo ngay một ticket nợ trong backlog có tên rõ ràng "Refactor shipping fee engine — Q1 sau sale", gắn nhãn tech-debt, và viết một dòng tác động: "Nợ này khiến mọi thay đổi giá ship phải sửa tay, ước tính tốn 2 giờ/lần, ~5 lần/tháng". Sau mùa sale, team trả nợ trong sprint đầu của quý mới.
Bài học: Vay nợ không phải tội. Vay nợ mà không ghi sổ và không có kế hoạch trả mới là tội. Việc PM gắn con số "2 giờ x 5 lần/tháng" biến món nợ vô hình thành tài sản có thể quản lý.
Tình huống 2 — Startup SaaS và "vòng xoáy lãi mẹ đẻ lãi con"
Bối cảnh: Một startup SaaS B2B ở Singapore làm phần mềm quản lý kho, 18 tháng tuổi, 12 engineer. Để chạy đua với đối thủ, họ ship liên tục mà không bao giờ dành thời gian refactor. Velocity ban đầu là 40 story point/sprint. Sau một năm, vẫn cùng team đó, velocity rớt xuống 18 point/sprint — chưa tới một nửa. Mỗi feature mới phải đụng vào "module ma" mà không ai dám sửa. Hai engineer giỏi nhất nghỉ việc vì kiệt sức với codebase.
Diễn giải: Đây là lãi suất kép của technical debt. Khi PM cuối cùng ngồi xuống tính toán, họ nhận ra: 22 point velocity bị "ăn" mỗi sprint chính là tiền lãi. Quy ra tiền, với chi phí team ~150 triệu đồng/sprint, công ty đang trả khoảng 80 triệu đồng/sprint tiền lãi mà không nhận lại giá trị nào. PM dùng chính con số này để thuyết phục CEO dành 20% năng lực mỗi sprint cho việc trả nợ trong 4 sprint liên tiếp ("debt sprint" xen kẽ). Velocity hồi phục lên 30 point sau hai tháng.
Bài học: Technical debt không trả thì lãi chồng lãi đúng nghĩa đen — velocity giảm theo cấp số, không phải tuyến tính. Và món vũ khí mạnh nhất của PM không phải là lý lẽ kỹ thuật, mà là quy đổi nợ ra tiền và thời gian mà lãnh đạo hiểu.
Tình huống 3 — Khi PM "bán" việc trả nợ cho lãnh đạo phi kỹ thuật
Bối cảnh: PM của một fintech tại Hà Nội cần thuyết phục ban giám đốc cho phép dừng 6 tuần phát triển feature để nâng cấp hệ thống xác thực (auth) cũ kỹ. Lần đầu trình bày, PM nói: "Code auth của chúng ta bị spaghetti, coupling cao, cần refactor." Ban giám đốc gật gù rồi từ chối — vì họ không thấy lý do kinh doanh.
Diễn giải: Lần thứ hai, PM thay đổi hoàn toàn cách kể chuyện. Họ không nói "spaghetti". Họ nói: "Hệ thống auth hiện tại khiến chúng ta KHÔNG thể tích hợp đăng nhập bằng VNeID — thứ mà 3 đối thủ đã có và khách hàng doanh nghiệp đang yêu cầu. Mỗi tuần trì hoãn, chúng ta mất khoảng 2 hợp đồng B2B, trị giá ~400 triệu/tháng. Việc nâng cấp 6 tuần này mở khóa cho cả lộ trình tích hợp định danh trong 12 tháng tới." Lần này được duyệt ngay.
Bài học: Lãnh đạo phi kỹ thuật không mua "code sạch". Họ mua "khả năng làm điều mà hiện tại không làm được", "giảm rủi ro mất tiền", hoặc "tăng tốc độ ra thị trường". Nhiệm vụ của Technical PM là dịch ngôn ngữ kỹ thuật của engineer sang ngôn ngữ giá trị của lãnh đạo.
Hướng dẫn từng bước
Đây là quy trình thực dụng để một Technical PM quản lý và trao đổi về technical debt.
Bước 1 — Làm cho nợ trở nên hữu hình (visible). Tạo một mục riêng trong backlog hoặc một nhãn tech-debt. Mỗi món nợ phải có: mô tả ngắn, vị trí trong hệ thống, và quan trọng nhất — tác động đo được (impact). Đừng chấp nhận ticket nợ kiểu "refactor module X" mà không có dòng "việc này hiện khiến chúng ta chậm ở đâu".
Bước 2 — Lượng hóa lãi suất. Với mỗi món nợ lớn, hỏi engineer ba câu: (1) Nó làm chậm chúng ta bao nhiêu mỗi lần đụng vào? (2) Chúng ta đụng vào nó bao nhiêu lần một tháng? (3) Nó đang chặn feature/cơ hội nào? Nhân ba con số này lại bạn có "tiền lãi hàng tháng" — vũ khí trao đổi mạnh nhất.
Bước 3 — Ưu tiên hóa. Không phải món nợ nào cũng đáng trả. Dùng ma trận đơn giản: trục đứng là "lãi suất" (nó ăn velocity nhiều hay ít), trục ngang là "có nằm trên đường đi của roadmap không". Ưu tiên nợ vừa lãi cao vừa chặn đường roadmap. Nợ lãi thấp ở góc xa của hệ thống thì cứ để đó — trả nợ vô tội vạ cũng là lãng phí.
Bước 4 — Phân bổ năng lực theo nguyên tắc, không theo cảm tính. Cách phổ biến và bền vững nhất: dành một tỷ lệ cố định mỗi sprint cho việc trả nợ — thường 15–20%. Một số team dùng "boy scout rule" (dọn sạch hơn chỗ mình vừa đi qua) cho nợ nhỏ, và "debt sprint" định kỳ cho nợ lớn. Việc đặt ra nguyên tắc trước giúp bạn không phải đấu tranh xin phép từng lần.
Bước 5 — Trao đổi đúng đối tượng. Với engineer: nói bằng ngôn ngữ kỹ thuật và lắng nghe — họ là người cảm nhận lãi rõ nhất. Với lãnh đạo: nói bằng tiền, thời gian, rủi ro, cơ hội. Với khách hàng (nếu cần): nói bằng độ ổn định và tính năng tương lai. Cùng một món nợ, ba câu chuyện khác nhau.
Bước 6 — Đóng vòng lặp. Sau khi trả nợ, đo lại velocity, bug rate, hoặc thời gian onboarding để chứng minh ROI. Điều này xây dựng lòng tin để lần sau xin nguồn lực trả nợ dễ hơn.
Lỗi thường gặp & mẹo
Lỗi 1 — Coi technical debt là "việc của engineering, không phải của PM". Đây là sai lầm chí mạng. Velocity và khả năng dự đoán roadmap là trách nhiệm trực tiếp của PM, mà cả hai đều bị technical debt bào mòn. PM lờ debt = PM tự bịt mắt mình.
Lỗi 2 — Để engineer trình bày debt bằng ngôn ngữ kỹ thuật trước lãnh đạo. "Coupling cao", "thiếu test coverage", "cyclomatic complexity" — lãnh đạo nghe xong không hành động. Mẹo: PM đóng vai phiên dịch, biến mọi món nợ thành câu "việc này khiến chúng ta không thể / chậm / rủi ro / tốn X".
Lỗi 3 — Trả nợ tất tay (big rewrite). Cám dỗ "viết lại từ đầu" gần như luôn là cái bẫy. Joel Spolsky gọi đây là "sai lầm tệ nhất một công ty phần mềm có thể mắc". Mẹo: trả nợ tăng dần (incremental), bám theo các feature đang làm, thay vì đóng băng sản phẩm để rewrite.
Lỗi 4 — Không bao giờ vay nợ vì sợ debt. Ngược lại cũng sai. Một số PM cầu toàn, ép team làm "đúng chuẩn" mọi thứ, bỏ lỡ cửa sổ thị trường. Nhớ lại Cunningham: vay nợ thận trọng, có chủ đích là khôn ngoan. Mẹo: hỏi "nếu vay món nợ này, ta được gì và kế hoạch trả ra sao?" — nếu trả lời được cả hai, cứ vay.
Lỗi 5 — Trộn lẫn debt với bug và feature trong cùng một backlog không phân loại. Khi mọi thứ trộn lẫn, debt luôn thua trong cuộc đua ưu tiên vì nó không "khẩn cấp". Mẹo: tách nhãn rõ ràng và bảo vệ ngân sách 15–20% cố định.
Mẹo vàng: Mỗi quý, làm một buổi "debt review" 60 phút với tech lead, đi qua top 5 món nợ lớn nhất, cập nhật lãi suất ước tính, và quyết định trả/hoãn. Buổi họp nhỏ này giúp debt luôn nằm trong tầm nhìn thay vì âm thầm lớn lên.
Bài tập thực hành
Bài tập 1 — Lập sổ nợ. Lấy một sản phẩm bạn đang làm (hoặc một sản phẩm bạn dùng hằng ngày, giả định). Liệt kê 5 món technical debt khả dĩ. Với mỗi món, viết một dòng tác động theo công thức: "Nợ này khiến chúng ta [chậm/không thể/rủi ro] ở [đâu], ước tính [con số]."
Bài tập 2 — Phân loại theo ma trận Fowler. Đặt 5 món nợ ở Bài tập 1 vào ma trận 2x2 (deliberate/inadvertent × prudent/reckless). Món nào là nợ tốt cần chấp nhận? Món nào là tín hiệu cảnh báo về năng lực team?
Bài tập 3 — Viết "pitch" trả nợ. Chọn món nợ lãi cao nhất. Viết một đoạn 5 câu thuyết phục một CEO phi kỹ thuật chi 4 tuần để trả nó. Quy tắc: KHÔNG được dùng bất kỳ thuật ngữ kỹ thuật nào (cấm "refactor", "coupling", "architecture"). Chỉ nói bằng tiền, thời gian, rủi ro, cơ hội.
Bài tập 4 — Thiết kế chính sách. Đề xuất một chính sách phân bổ năng lực trả nợ cho team 8 engineer của bạn. Tỷ lệ bao nhiêu phần trăm? Theo cơ chế nào (boy scout rule, debt sprint, hay kết hợp)? Bảo vệ lựa chọn của bạn trong 3 câu.
Tóm tắt
Technical debt, theo ẩn dụ gốc của Ward Cunningham, là việc vay tốc độ phát triển hôm nay bằng lời hứa trả nợ ngày mai — và "lãi suất" của nó biểu hiện qua velocity giảm, bug tăng, và khả năng dự đoán roadmap suy yếu. Vay nợ một cách thận trọng, có chủ đích là khôn ngoan; vay mà không ghi sổ và không trả mới là tai họa, vì lãi chồng lãi theo cấp số.
Là Technical PM, ba việc bạn phải làm: (1) làm cho nợ trở nên hữu hình và lượng hóa được lãi suất của nó; (2) ưu tiên trả những món nợ vừa lãi cao vừa chặn roadmap, với ngân sách cố định 15–20% mỗi sprint; (3) trao đổi đúng đối tượng — engineer bằng ngôn ngữ kỹ thuật, lãnh đạo bằng tiền và cơ hội, khách hàng bằng độ ổn định. Tránh hai cực đoan: lờ debt như "việc của engineering", và big rewrite tất tay. Hãy nhớ ba tình huống trong bài — vay đúng lúc như sàn TMĐT mùa sale, vòng xoáy lãi kép của startup SaaS, và nghệ thuật "bán" việc trả nợ cho lãnh đạo của PM fintech. Quản lý technical debt giỏi không phải là tránh nợ, mà là vay và trả một cách có kỷ luật.