見出し画像

リードタイムを短くせよ。具体例と理論と統計から理解する-その1


はじめに

hi-outcomeの中森です。
本連載では、実験・理論・統計・歴史の観点からソフトウェア開発の文脈でリードタイムを短くすることが決定的に重要であることを説明したいと思います。
我々ソフトウェア開発者が改善活動を行う際にはいくつもの方法があります。
しかし、その効果が個人の体験談に基づく再現性の低いものであったり、自身の置かれた文脈によって全く実行不能であったりするためにうまくカイゼン活動が推進できないことも多いと思います。
そこで、今回と次回に分けてリードタイムをカイゼンする行為がリーンの本質であること。
誤解を恐れずに言うと、リードタイムのカイゼンを行うことが、現代のエンジニアリングにとって必須の作業であることをお伝えしたいと思います。

本記事のまとめ

本記事はやや長いので、以下のまとめを意識して読んでいただけると全体像を見失うことなく読めるかと思います。

  • 封筒の実験、ジャグリングの実験、キングマンの公式からバッチサイズを小さくし、稼働率を低く抑えることによってリードタイムの短縮につながる

  • リードタイムの短縮が企業組織全体のパフォーマンス(収益性・市場占有率・生産性)の予測要因になることがState of DevOpsレポートで明らかになっている。

では話を前に進めていきましょう。
まずは、リードタイムについて理解を深めるために、まずは『リーン・スタートアップ』で一躍有名になった封筒の実験から見ていきましょう。

封筒の実験

実験内容

この実験では、紙を折って封筒に入れ、封をして切手を貼るという単純な作業を行います。具体的には、以下の2つの作業を比較します。

1. 大きなバッチサイズで作業

こちらの作業では、10枚の紙を一度に折り、次にその10枚を一度に封筒に入れます。
その後、10枚の封筒の封を閉じます。
そして、最後に10枚の封筒に切手を貼ります。

2. 小さなバッチサイズで作業(一個流し)

こちらの作業では1枚の紙を折ってすぐに封筒に入れ、封をして切手を貼ります。
そして、次の作業に進むという具合です。

結果

さてどちらの方が作業がより速く終わるでしょうか?
つまりどちらの方がリードタイム全体が短くなるでしょうか?
資本主義の前提とする分業と専門化の力強いハーモニーを信じるならば、前者のまとめて同じ作業を行い、次の工程に進んでいくというやり方が速いように思われるかと思います。
この実験を初めて見た時の私は前者の方が速いと思いました。
しかし、その予想に反して後者の小さなバッチサイズでの作業の方が速くなるのです。
では、いったいなぜそのような結果になるのでしょうか?

バッチサイズを小さくした方が速くなる理由

問題の早期発見

バッチサイズを小さくし、1枚ずつ処理する方法では、紙が正しく折れていない、または封筒に入らないといった問題にすぐ気づくことができます。
早い段階でミスに気づくことができれば、修正範囲も小さくなります。
紙を10枚折った後に、いざ封筒に詰める段階で紙が封筒に入らないと気づいた場合だと10枚すべてを折り直す必要があります。

修正の容易性

問題が早期に発見できれば、当然ですが修正も容易です。
なぜなら、バッチサイズが小さければ問題が発生した場合に、1枚だけ修正すればよいからです。
一方で、まとめて全てのタスクを行う方法では、前工程でのミスがそっくりそのまま修正範囲になるので修正範囲が大きくなるため命取りになりやすいです。

教訓

一人で行う単純な作業でもバッチサイズを小さくすることで生産性が向上する

この実験は一人の人間が行う非常に単純な作業ですが、それでもバッチサイズを小さくするメリットが明確に示されています。
作業の効率性が向上するだけでなく、問題の早期発見と修正の容易性が高まるという視点がソフトウェア開発の文脈においても非常に示唆的です。
このような一人が行う非常に単純な作業ですらバッチサイズを小さくし、一個流しで作業をすることがリードタイムを短く保ち、生産性も高めることにつながるのです。

疑問

ただ、この実験がソフトウェア開発のような現実の複数人で行う複雑な作業にも通じるか疑問に思う読者もいらっしゃると思いますので、ここでは、実際に複数人で行う複雑な作業についてもバッチサイズを小さくすることが重要であることを1つ具体例を挙げて説明したいと思います。

思考実験:複数人で行う複雑な作業

ここでは、5人が円になりジャグリングをしているシチュエーションを考えます。

シチュエーション1

各人が1個の球をジャグリングしながら、右隣の人に球を1個渡していき、当初自分が持っていた球が左横の人に渡るまで繰り返します。

シチュエーション2

各人が4個の球をジャグリングしながら、右隣の人に球を1個ずつ渡していき、最終的に自身が当初持っていた球がなくなるまで繰り返します。

結果

この時、どちらの作業がより早く終わるでしょうか?
当たり前ですが、シチュエーション1です。
では、なぜ、シチュエーション1の方がスムーズに作業ができるのでしょうか?
裏を返せば、シチュエーション2だとなぜより時間がかかってしまうのでしょうか?
ここではWIPと稼働率という観点で考えたいと思います。

WIP(Work In Progress)とは

WIP、または「Work In Progress」は、ある時点で進行中の作業やタスクの量を示す用語です。
このジャグリングの例で言えば、WIP(Work In Progress)は各人が一度にジャグリングしているボールの数になります。
WIPが少ない場合、すなわち進行中のタスクが少ない場合、個々のタスクの完了速度が速くなり、全体の流れがスムーズになる可能性があります。
一方、WIPが多い場合、すなわち進行中のタスクが多い場合、各タスクの完了に時間がかかり、タスク間の遷移が滞りがちになります。これは、リソースが過剰に割り当てられ、効率が低下する可能性があります。

稼働率とは

稼働率は、個人またはシステムが実際に作業を行っている時間の割合を指します。
各人が処理する球が少ない状態、つまりWIPが少ない状態では、各人の稼働率が低いです。
一方で、各人が処理する球が多い状態、つまりWIPが多い状態では、各人の稼働率が高くなりやすいです。

稼働率の高さがリードタイムを悪化させる理由

理由1: 待ち時間が発生する

自身でも多くの球を捌きながら、多くの球を捌く他者にパスできるタイミングを見計らうことが非常に難しいというのがあります。
つまり、球を渡す際にタイミングを見計らうという待ち時間が発生するということです。
それだけでなく、仮に球を渡したとしてその人の稼働率のキャパシティをオーバーしてしまわないように全体で調整するコストもかかってくるでしょう。

理由2:稼働率の高い場所が全体のボトルネックになる

これは稼働率の高い低いが極めて属人的になってしまうことに起因します。
どういうことかというと、ジャグリングの技術が低く、少ない球、ここでは2つの球でもジャグリングするのが精一杯な人がいたとします。
この時、この人にとっては、2つの球をジャグリングすることは稼働率が極めて高い状態であると言えます。
そのような人が4つの球をジャグリングしながら、他者に球をパスすることは困難を極めます。
仮に他の4人にとって、球を4つジャグリングすることが稼働率が低い状態であったとしても、残り1人の稼働率が高い状態により、そこが大きなボトルネックになり、球の流れ全体、つまりフローが滞ってしまいます。

理由3:高稼働の場合の方が、突発事象による影響を大きく受けてしまう

稼働率が非常に高い状態は突発的な事態の発生に大きな影響を受けます。
例えば、1人がボールを落としたり、1人がボールを投げるタイミングを間違えたりすると、そこでリズムが崩れ、その影響が全体に波及し、球の流れが滞ってしまいます。
予想されうる突発事象にも影響を受けますが、予想外の突発事象にも当然大きな影響を受けます。
例えば、犬が突然乱入してくるなどです。低稼働の状況では、犬が登場しても冷静にボールを処理できる可能性が高いですが、高稼働な状況ではそうとは言えないでしょう。

教訓

このように、バッチサイズが大きい状態では、稼働率が高くなりやすく、バッチサイズが小さかった場合には起こり得なかった様々なコストが発生したり、突発的な事態に極めて脆弱になるため、フロー全体が滞ってしまうということが起こり得るのです。
やや踏み込んで言えば、複数人でかつ複雑な作業の場合こそ、バッチサイズを小さくすることが非常に重要なのです。
バッチサイズが小さければ、複数人になったとしてもリードタイムを短く保つことができます。
一人で行う単純な封筒の例でもバッチサイズを小さくすることに大きなメリットがあるのだから、複数人で行う複雑な作業においてもバッチサイズを小さくすることに大きなメリットがあると私が考える所以はここにあります。

ただ、これはあくまでも具体例じゃないかと思う読者もいらっしゃると思います。
確かにその通りです。
ではここからは、ジャグリングのような事態が普遍的に起こる事態であることを理論の側面と統計の側面からさらに補足していきます。

理論:キングマンの公式

キングマンの公式は、待ち行列理論において、システムの待ち時間を評価するための数学の公式です。
この公式は、スループット時間が稼働率と変動によってどのように変わるかを表現したもので、次のようなグラフとなります。


キングマンの公式のグラフ1

※横軸に稼働率
※縦軸にスループット時間

用語

スループット時間 (Throughput Time)
スループット時間は、システムを通過するのに要する合計時間を指します。
これには、サービス時間(システムでの処理時間)と待ち時間(キューでの待機時間)の両方が含まれます。
キングマンの公式では、スループット時間は平均サービス時間と平均待ち時間の和として計算されます。
要は、価値が加わっている時間が平均サービス時間で、なんら付加価値が加わらない時間が平均待ち時間です。
ここではスループット時間はリードタイムと同義だと考えて問題ないです。
変動 (Variability)
変動は、システム内のプロセスのランダム性や予測不能性を示します。
稼働率 (Utilization Rate)
稼働率は、実際に作業を行っている時間の割合を示します。稼働率が1に近づくほど高稼働だと考えます。

さて、上記のグラフから以下のことがわかります。

高稼働になればなるほど、スループット時間が劇的に増加していく。

稼働率が低い領域(例:0.2や0.4など)では、曲線の傾きは比較的緩やかです。これは、稼働率が少し上がっても、スループット時間はそれほど大きく増加しないことを意味します。
一方で、稼働率が高い領域(例:0.8や0.9など)に近づくと、曲線の傾きは急激に大きくなります。これは、高い稼働率でさらに少し稼働率が上がると、スループット時間が急激に増加することを示しています。
つまり、先のジャグリングの例で言うと、高稼働の状況では、球を渡すための待ち時間が発生したり、高稼働のところが全体のボトルネックになるため、スループット時間が増加すると言う話につながるわけです。

変動が大きければ大きいほど、スループット時間が長くなる。

次に、変動の差を反映させたグラフを確認いただければと思います。


キングマンの公式のグラフ2

破線の高稼働のグラフが実線の低稼働のグラフよりも左に位置していることがわかるかと思います。
これは同じ稼働率でも、変動の高低によってスループット時間が変わることを指しています。
変動が大きいと稼働率が同じでもスループット時間が長くなってしまうのです。
例えば、稼働率が0.8の時の2つのグラフを比較すると高変動を表現した波線のグラフの方がスループット時間が長くなっているのがお分かりになるかと思います。
つまり、先のジャグリングの例で言うと、誰かが球を落とすという事態や球を渡すタイミングを誤るなどの事態が発生する頻度が高いと全体のリズムが崩れたり、球を拾う時間が発生したりでスループット時間が長くなると言う話につながるわけです。
しかも、高稼働な状態であればあるほど変動の影響を大きく受けます。
球の数が少なければ、球が落ちたとしてもすぐに拾って作業を再開できますが、球の数が多くなればなるほどそういうわけにはいかなくなるでしょう。
さて、ここまでざっとですが理論的な側面で説明したのですが、理論は理論とまだご納得いただけない方に向けて、統計データをご紹介したいと思います。
その前にここまでの内容を整理しておきます。
バッチサイズが大きい状況では以下の問題が発生するためリードタイムが長くなりがちです。

  1. 稼働率が高い状況では、待ち時間が発生してしまう

  2. 高稼働のリソースが一つでもあるとその他が低稼働だったとしても全体のボトルネックになる

  3. 高稼働な状態ほど、変動要因に大きな影響を受けてしまいます。

    1. ソフトウェア開発の文脈で解釈すると、高負荷状態(多くのプロジェクトやタスクが同時に進行中)では、予期せぬ遅延や変更(変動)がプロジェクト全体の遅れを引き起こしやすくなります。

統計的アプローチ: State of DevOpsレポート

ここまで、リードタイムを短くすることの重要性を説いてきたわけですが、これらが統計的に観察可能なのかというと、ソフトウェア産業を対象にした膨大な調査によって、統計的にも観察されたというのが、2013年から毎年実施されているState of DevOps レポートの大きな功績なわけです。
※現在は、GoogleとPuppet社が毎年実施しています。
State of DevOpsレポートをざっくり一言でまとめると、エンジニアリング組織のパフォーマンスの高低が組織のパフォーマンス(収益性・市場占有率・生産性)の予測要因になるという事です。
ここでいうエンジニアリング組織のパフォーマンスの高低を決める要素4つを指して4keysと言うのですが、その中にリードタイムがあるのです。
つまり、リードタイムを筆頭とする数値が高いエンジニアリング組織を抱える企業の業績は高いと予想できるわけです。

4keysとは?

State of DevOps レポートの研究で特定された4つの重要な指標を指します。
4keysは以下の通り。
詳しくは、t_wadaさんの『質とスピード』講演の資料をご確認ください。

デプロイ頻度
特定期間内でどれだけ迅速に新機能や修正をリリースできるかを示す指標

リードタイム(変更のリードタイム)
変更がコードに組み込まれてから実際にプロダクトにリリースされるまでの時間

変更失敗率
アプリケーションへの変更のうち、サービス低下を招いたケースや修正作業が必要となったケース、パッチが必要となったケースの発生率

平均修復時間(MTTR)
本番環境での障害から回復するまでの平均時間

まとめ

さて、ここまで封筒の実験、ジャグリングの実験、キングマンの公式、統計的側面を通してバッチサイズを小さくし、稼働率を抑えることがリードタイムの短縮につながり、組織全体のパフォーマンス(収益性・市場占有率・生産性)の予測要因になることを説明してきました。
ここまで来れば、バッチサイズを小さくし、一個流しで機能開発を行うこと、つまりリードタイムを短く保つことがいかに大切かはご納得いただけたのではないでしょうか。

ただ、私が観察する限り、多くのソフトウェア企業では、こういった正しい事象とは真反対の事態が起こっているように感じます。

リソース効率の甘い誘惑

それは、リソース効率の甘い誘惑というアンチパターンに多くの企業が引っかかっているからだと筆者は考えています。
それは、経営・マネジメント・現場が生産性を高めるために各人の稼働率に着目し、稼働率を高めているのにも関わらず(むしろ稼働率を高めていくがゆえ)にどんどんとリードタイムが伸びていき生産性が下がってしまうという事態です。
私はリソース効率の罠と呼んでいます。

アンチパターン
一見すると有効な解決策に見えるが、実際には問題を悪化させたり、新たな問題を引き起こしたりするような解決策のこと

一見、各人の生産性に注目し、稼働率を上げていく戦略は正しいように思いますし、我々はこうすることが正しいとさまざまな場所で教わってきました。
実際、企業会計において、人は人的資本としてとらえられます。機械や設備と同じように人をリソースとして扱っているわけです。リソースは遊休させるわけにはいかないので、稼働率を上げることが企業経営上でも正当化されているわけです。
ただ、稼働率を高める作戦はどこかで破綻をきたしてしまいます。
ですが、現実問題として企業のあらゆるところで稼働率に注目し高稼働の状況を作り出しそこが全体のボトルネックになっている場面をよく目にします。

余談 of 余談
名著『SQLアンチパターン』で登場してくるアンチパターンのような命名にしたいので、筆者は心の中でThe Sweet Flavor of Resource Efficiencyと呼んでいます。

パラダイムシフトを起こす

さて、今こそ、ソフトウェア開発にパラダイムシフトを起こす時なのです。
各人の稼働率を高めることにフォーカスするのではなく、リードタイムに注目し、1つ1つのフローを早く流すことにフォーカスすべきなのです。
短いリードタイムを持続的に維持できるようにリソースを投下すべきなのです。
そのために、経営・マネジメント・現場が連携すべきなのです。
リードタイムを計測し、一つの機能が早く早くリリースされる技術・プラクティス・組織・文化に投資すべきなのです。

さてどうする?

次にエンジニアリングの文脈・プロダクトマネジメントの文脈・企業経営の文脈でパラダイムシフトを起こしていくための方法について考えていきたいのですが、その前に時計の針を巻き戻して、ソフトウェアの歴史を俯瞰して眺めることが非常に重要です。
実験・理論・統計の他に歴史という観点を手にいれることは非常に強力な武器となります。
では、時計の針を1990年代に戻しましょう。
そうアジャイル開発ムーブメントのあの時代です。
ただ、記事もだいぶ長くなってしまったので、今回はこれで終わりとし、歴史のお話は次回にまわします。

次回予告

次回は、アジャイル・リーン・DevOpsというソフトウェア産業を貫く3つの大きな幹の歴史の話から始めて、リーンの本質に迫ってみたいと思います。
また、リードタイムを持続的に短くするためのプラクティスについて説明します。

おわりに

私たち「Hi-Outcome」は、開発チームの規模が10-100名の企業を中心に、開発スピード向上にコミットした開発支援を行っています。

開発にお悩みの方がいましたら、是非お気軽にお問い合わせください。
開発スピード向上サービス: https://corp.hi-outcome.com/
開発の予測精度向上サービス: https://corp.hi-outcome.com/inspection