技術的負債とリリース速度 — 利息を測り返すときを決める
一言でいうと
技術的負債は、悪いものではなく、利息が付く借入です。初期の製品は、速く学ぶために、わざと借ります。問題は、利息を測らないことです。デプロイ記録と作業記録から、利息(計画外に漏れる時間)とデプロイの安定性を測り、返すコスト・回収期間・先送りされる機能の価値を、1行に並べれば、「今返すか」が、意見ではなく計算になります。
なぜ必要なのか
小さなチームは、2つの声の間で揺れます。「今直さなければ、永遠に直せない」と、「顧客が望む機能から出さなければ生き残れない」です。どちらも正しい言葉なので、会議が終わりません。結論は、たいてい、声が大きいほうが決めます。
マーティン・ファウラーは、技術的負債の記事で、このメタファーを、ウォード・カニンガムが1992年のOOPSLAの経験報告で作ったと書き、コードの欠陥のせいで、機能を加えるたびに追加でかかる労力を利息、その欠陥を取り除く労力を元本と説明しています。その枠組みをそのまま使えば済みます。利息が大きく、増えているのに、元本が小さければ、返すほうが速く、利息が小さければ、その時間に機能を出すほうがよいです。
どう動くのか
デプロイの安定性: DORA指標: dora.devの指標の案内は、スループットの指標として、変更のリードタイム(バージョン管理にコミットされた変更が、本番にデプロイされるまでの時間)・デプロイ頻度・失敗したデプロイの復旧時間を、不安定性の指標として、変更失敗率(デプロイの直後に、すぐ介入が必要だったデプロイの割合)と、デプロイの手戻り率(本番の障害のために行った、計画外のデプロイの割合)を挙げています。負債がたまったモジュールは、しばしば、デプロイが間遠で、失敗が多く、復旧が長く、障害対応のデプロイが多いです。
平均より中央値: リードタイムには、数日ずつ寝かされた変更が数件混ざります。平均は、その数件に引っ張られて、典型的な変更がどれだけかかるかを覆い隠します。このラボは、中央値と平均を並べて書き、違いを見られるようにします。
利息を測る: 週ごと・モジュールごとに記録した「計画外の作業時間」(バグ・障害対応)が、利息です。平均だけを見ず、トレンドを見ます。最初の4週間と最後の4週間を比べて、増えているなら、返す決定の基準は、過去の平均ではなく、最近の利息でなければなりません。
返すかどうかを判断する: このラボは、次の順序で計算します(すべての値とルールは例です)。
| 値 | 計算 |
|---|---|
| 節減(時間/週) | 最近の利息 × リファクタリングが減らす割合 |
| 回収期間(週) | リファクタリングのコスト(時間) ÷ 節減 |
| 期間の純節減(ウォン) | (節減 × 判断の期間 − コスト) × 1時間あたりのコスト |
| 遅延コスト(ウォン) | (コスト ÷ チームの週あたりの容量) × 機能の週あたりの価値 |
リファクタリングしている間、チームが機能を作れなければ、その分だけ機能が遅れ、その機能が毎週稼いでいたはずの価値が失われます。これが、遅延コスト(cost of delay)です。回収期間が最も短い候補の、期間の純節減が、遅延コストより大きければ、先に返し、そうでなければ、機能を先に出します。「リファクタリングが利息を70%減らす」のような見積もりは、間違うことがあるので、見積もり値を書いておき、返した後の実際の利息と比べるところまでが、1周です。
負債をどこに記録するか: 利息を測るには、計画外の作業を、モジュールごとに記録しなければなりません。大がかりなツールは必要ありません。イシュートラッカーに、「計画外」の印とモジュール名、費やした時間だけを残せば、週ごとの合計が出ます。記録がなければ、利息は「みんな忙しい」という感覚としてだけ存在し、感覚は、機能リクエストの数字に勝てません。
すべての負債を返す必要はありません: もうすぐ捨てる実験コードや、ほとんど変わらないモジュールの負債は、利息が0に近いです。ファウラーが言うように、利息は、そのコードを変更するときに付きます。そのため、返す候補は、「汚いコード」ではなく、「頻繁に変更されて、計画外の作業を生むコード」から選びます。変更頻度と計画外の作業が、ともに高いモジュールが、最初の候補です。
現場での姿
- 決済モジュールだけを触るとデプロイが失敗し、復旧に半日かかり、毎週金曜日が障害対応で終わります。利息は記録されていないので、誰も大きさを知りません。
- 「リファクタリングすれば速くなる」という言葉だけがあり、どれだけ、いつからなのかの数字がないので、毎回機能に押されます。
- 逆に、利息がほとんどない古いコードを、「見たくないから」と直すために、リリースを1か月延ばします。
間違いに気づく方法
- リードタイムの平均と中央値が大きく違えば、長い裾があるという意味です。その裾の変更を別に開いて、原因を見ます。レビュー待ちなのか、デプロイウィンドウを待ったのか、です。
- 変更失敗率の分母が、デプロイ数かどうかを確認します。障害数や日数で割ると、デプロイが頻繁なチームが不利になります。
- 利息の見積もりに12週間の平均を使ったなら、トレンドも一緒に見ます。増えている利息を平均で判断すると、返すべきときを逃します。
- 決定の数週間後に、計画外の作業を測り直して、見積もりと比べます。比べなかった見積もりは、次の決定でも同じ大きさで間違います。
次のラボですること
12週間のデプロイ・作業記録で、サービス別のDORA指標を計算し、リードタイムの中央値と平均がなぜ違うのかを見ます。モジュール別の利息とそのトレンドを測り、リファクタリング候補2つの、回収期間・純節減・遅延コストを計算して、ルールどおりに決定します。採点ツールは、あなたの関数を、揺さぶった記録でも再実行します。