概要
定性表現を数値に翻訳する
「本日20時頃」「しばらくして」「一部のお客様」は経営判断の材料にならない。検知(MTTD)・対応開始・復旧(MTTR)を時刻付きで数値化し、影響人数・キャンペーン期限切れによる除外人数まで配信キューの動きから算出する。あらゆるビジネス報告の基本作法。
5 Whys で技術的根本原因まで掘り下げる
「システムエラーが発生した」で止めず、Circuit Breaker未実装 → タイムアウト長期化 → リトライ多重発火 → リソース逼迫 → スケール上限到達という設計判断まで遡る。対症療法ではなく恒久対策につながる。
RICE で対策に優先順位をつける
対策を思いつくまま列挙せず、Reach × Impact × Confidence ÷ Effort で機械的にスコアリングする。限られたエンジニア工数の配分根拠を「監視強化する」ではなく数値で経営に説明できる。
SLAエラーバジェット + ROI で経営判断を支援する
エラーバジェット消費率で障害の深刻度を共通言語化し、機会損失(3,000万円)vs 対策投資(30万円)という非対称性を示す。「対策に30万円かかります」だけでは通らない稟議が、対比で即決になる。
問題
ECサイト MOps チームのシニアエンジニアとして、GWキャンペーン一斉配信中に発生した障害のインシデント事後報告書を経営会議に提出することになった。後輩が作成した Bad ドラフトをレビューし、7つの問題点を洗い出して Good 報告書へ再設計せよ。
前提数値(正)
- キャンペーン配信対象: 120万人。20:00に配信開始
- 20:15、配信 API(Cloud Run)で障害発生。20:15時点で40万人(33.3%)に配信済み
- 検知: アラート閾値が緩く、カスタマーサポートへの「メールが届かない」問い合わせで気づいた。障害発生から検知まで 15分(MTTD)
- 検知後、対応開始〜復旧まで 65分(MTTR)。合計ダウンタイム 80分(20:15〜21:35)
- 障害中に配信キューへ滞留した80万人のうち、復旧後の自動リトライで55万人へは当日23:00までに配信完了。残り 25万人はキャンペーン期限(当日23:59)に間に合わず配信対象から除外
- 平均配信あたり CVR: 2.5%、平均購入額: 4,800円
- SLA: 稼働率 99.9%(30日ローリング)。エラーバジェット = 30日 × 24h × 60分 × 0.1% = 43.2分/月
- 根本原因(5 Whys 要約): Circuit Breaker 未実装 → 下流の外部配信ゲートウェイ API のタイムアウト設定(30秒)が長すぎる → リトライが多重発火 → Cloud Run インスタンスの CPU/メモリが逼迫 →
max-instances(上限20)に到達しスケールできず新規リクエストが 5xx - エンジニア単価: 80万円/月(20営業日 = 4万円/人日)
悪い報告書 (Before)
件名: キャンペーン配信障害について
本日20時頃、キャンペーンメール配信システムに障害が発生しました。
← 問題①: MTTD/MTTRの数値化なし
原因はシステムエラーです。しばらくして復旧しましたが、
← 問題④: 5 Whysの深掘りなし「システムエラー」止まり
一部のお客様にメールが届かなかった可能性があります。
← 問題②: 影響人数・除外人数が未算出
← 問題③: 機会損失の金額試算がない
対応策:
・システムの監視を強化する
・エラーハンドリングを見直す
・再発防止に努める
← 問題⑤: 優先順位・工数見積・期待効果なし
← 問題⑥: SLA/エラーバジェットとの接続なし
← 問題⑦: 再発防止投資のROI試算なし
以上、ご報告まで。
ヒント(段階的開示)
ヒント1 — 方向性
ヒント2 — アプローチ
- 問題①②: 「しばらくして」→ 検知(MTTD)・対応開始・復旧(MTTR)を時刻付きで数値化
- 問題③: 「一部のお客様」→ 配信失敗率・除外人数を配信キューの動きから算出
- 問題④: 影響人数 × CVR × 平均購入額で機会損失を金額換算
- 問題⑤: 「システムエラー」→ 5 Whys で Circuit Breaker 未実装・タイムアウト設定・スケール上限まで掘り下げる
- 問題⑥: 対策の箇条書き→ RICE(Reach×Impact×Confidence÷Effort)で優先順位付け、工数見積もり付き
- 問題⑦: SLA 99.9%/エラーバジェット43.2分との対比で今回の障害の深刻度を示し、対策投資のROIを試算する
ヒント3 — 誘導
【機会損失】
除外人数 × CVR × 平均購入額 = 25万人 × 2.5% × 4,800円 = ?
【エラーバジェット消費率】
エラーバジェット(43.2分) に対する今回のダウンタイム(80分)の消費率 = 80 / 43.2 = ?
【RICEスコア】
RICE = (Reach × Impact × Confidence) / Effort(Effort=人日)
対策候補ごとに算出し、優先順位を決める
【ROI】
ROI(%) = (期待される年間機会損失回避額 − 投資額) / 投資額 × 100
問題点分析(7点)
| # | 問題点 | 分類 | 改善方法 |
|---|---|---|---|
| 1 | タイムラインが定性的(「本日20時頃」「しばらくして」) | 定量化 | 検知(MTTD)・対応開始・復旧(MTTR)を時刻付きで数値化 |
| 2 | 影響範囲が未算出(「一部のお客様」) | 定量化 | 配信キュー内訳から影響人数・除外人数を算出 |
| 3 | 機会損失の金額試算がない | 財務 | 影響人数 × CVR × 平均購入額で売上インパクト換算 |
| 4 | 根本原因の深掘りがない(「システムエラー」止まり) | 分析 | 5 Whys で Circuit Breaker 未実装まで掘り下げ |
| 5 | 対策に優先順位・工数見積・期待効果がない | 意思決定 | RICE(Reach×Impact×Confidence÷Effort)でスコアリング |
| 6 | SLA/エラーバジェットとの接続がない | SRE | エラーバジェット消費率で深刻度を定量化 |
| 7 | 再発防止投資のROI試算がない | 財務 | 機会損失回避額 vs 投資額でROI試算 |
タイムライン(MTTD/MTTR)と RICE優先順位チャート
模範解答
| 項目 | 内容 |
|---|---|
| Who | 配信対象120万人の顧客、MOpsエンジニア2名(対応)、カスタマーサポート(一次検知) |
| What | GWキャンペーン一斉配信中の配信API(Cloud Run)障害。5xxエラーで新規配信不可 |
| When | 2026-07-16 20:15 発生 〜 21:35 復旧(ダウンタイム80分) |
| Where | Cloud Run 上の配信API。下流の外部配信ゲートウェイAPIとの連携部分 |
| Why | Circuit Breaker未実装により、下流APIのタイムアウト長期化がリトライの多重発火を招き、インスタンスのリソース逼迫とスケール上限到達につながった |
| Which | 案A: 恒久対策を全項目同時着手 / 案B: RICE優先順位順に段階着手(採用) |
| How | Circuit Breaker導入 + max-instances引き上げ + タイムアウト短縮 + アラート閾値見直し |
| How many | 影響: 除外25万人(配信対象の20.8%)。エラーバジェット消費率185% |
| How much | 機会損失3,000万円。対策投資38万円。詳細は各タブ参照 |
20:00 ─────── 20:15 ────── 20:30 ────── 21:35 ────── 23:00
配信開始 障害発生 検知 復旧 リトライ完了
(40万人配信済) (MTTD=15分) (MTTR=65分)
ダウンタイム = 20:15〜21:35 = 80分
検知が15分遅れた理由: アラート閾値がエラー率50%超で発報設定
(実際は20:20時点でエラー率90%超に達していたが閾値未達で無警報。
顧客問い合わせで人手検知)
配信キューの内訳(対象120万人):
配信済み(障害前) : 40万人(33.3%)
障害後リトライで当日配信完了: 55万人(45.8%)
期限切れで配信対象外 : 25万人(20.8%) ← 機会損失
機会損失 = 25万人 × CVR 2.5% × 平均購入額 4,800円
= 250,000 × 0.025 × 4,800
= 30,000,000円(3,000万円)
Why1: なぜ配信APIが5xxを返したか?
→ Cloud Run インスタンスが max-instances(20) の上限に到達し、
新規リクエストを処理できなかった
Why2: なぜインスタンス上限に到達したか?
→ 下流の外部配信ゲートウェイAPIへのリクエストが
タイムアウト(30秒)まで滞留し、1インスタンスあたりの
同時実行数が枯渇していた
Why3: なぜタイムアウトまで滞留したか?
→ 外部ゲートウェイAPI側で一時的な応答遅延が発生していたが、
こちら側にリトライの上限・バックオフ制御がなく、
失敗したリクエストが即座に再送され続けた
Why4: なぜ即座に再送され続けたか?
→ Circuit Breaker が実装されておらず、
下流障害を検知して呼び出しを一時遮断する仕組みがなかった
Why5(根本): なぜ Circuit Breaker が実装されていなかったか?
→ 配信APIの設計時、外部依存先の障害を前提とした
耐障害設計(Circuit Breaker / タイムアウト設計)が
要件に含まれていなかった
| 対策 | Reach | Impact | Confidence | Effort(人日) | RICEスコア |
|---|---|---|---|---|---|
| ① max-instances 引き上げ + スケール調整 | 9 | 2 | 0.8 | 1.0 | 14.4 |
| ② Circuit Breaker 導入 | 9 | 3 | 0.9 | 3.0 | 8.1 |
| ③ アラート閾値見直し(MTTD短縮) | 9 | 1 | 0.9 | 1.0 | 8.1 |
| ④ タイムアウト短縮 + 指数バックオフ | 9 | 2 | 0.8 | 2.0 | 7.2 |
| ⑤ キャンペーン当日配信のリトライ許容ポリシー事業合意 | 9 | 2 | 0.5 | 2.0 | 4.5 |
エラーバジェット(99.9% / 30日ローリング) = 43.2分/月
今回の障害ダウンタイム = 80分
消費率 = 80 / 43.2 = 185%
→ この1件だけで月間エラーバジェットを185%消費し、SLO違反が確定。
残り期間で他の障害は一切許容できない状態。
経営会議では「軽微な障害」ではなく「SLO違反級インシデント」
として報告する必要がある。
投資額(対策①〜④の実装工数):
① max-instances調整 0.5人日
② Circuit Breaker実装 5.0人日
③ アラート閾値見直し 1.0人日
④ タイムアウト短縮 1.0人日
合計 7.5人日 × 4万円/人日 = 30万円
期待効果:
同種障害の年間発生を保守的に2回と仮定した場合の
年間機会損失回避額 = 3,000万円 × 2 = 6,000万円
ROI = (6,000万円 − 30万円) / 30万円 × 100 ≒ 19,900%
回収期間: 障害を1回でも防止できれば即回収(投資30万円 ≪ 機会損失3,000万円/回)
ポイント解説
実務への応用
MOpsチームのキャンペーン配信基盤・決済連携・ベンダーAPI連携など、外部依存を持つシステムでは障害が避けられない。障害発生時に「原因と対応策」だけを報告するのではなく、機会損失(売上インパクト)とSLA毀損度(エラーバジェット消費率)を必ずセットで報告することで、再発防止投資の優先順位を経営に正しく判断してもらえる。
RICEスコアリングは障害対応の優先順位付けだけでなく、日々のバックログ優先順位付けにもそのまま使える汎用フレームワーク。5 Whysはポストモーテムの標準フォーマットとして、Circuit Breaker(耐障害設計)のような設計の必要性を組織に説明する際の論拠にもなる。
今日のまとめ
次のステップ
- 発展問題: 今回のCircuit Breaker導入をSREのpostmortemテンプレートとして標準化し、「MTTD短縮のためのアラート設計」(マルチウィンドウ・マルチバーンレートアラート)を組み込んだ次回インシデント対応フローを設計せよ。
- 参考: RICE スコアリング / 5 Whys(根本原因分析)/ SLA・SLO・エラーバジェット / MTTD・MTTR / ポストモーテム(Blameless Postmortem)/ 6W3H フレームワーク