# SLO とは？ プラットフォームチームのための実践ガイド

URL: https://upstreamapi.com/ja/journal/slo-toha
Type: blog
Locale: ja
Published: 2026-10-31
Updated: 2026-11-01

---

> SLOとは何か、エラーバジェットとバーンレートの仕組み、そしてリリースを自動で止める数字をロールアウトに組み込む方法を平易に解説します。

SLO とは、ある特定のユーザー向けの動作が、一定の期間にわたってどれだけ信頼できている必要があるかを示す目標値です。「30日間で、チェックアウトのリクエストの99.9%が800ミリ秒以内に成功する」はSLOです。「サイトは速いほうがいい」は願望にすぎません。数字そのものより重要なのは、その数字が何を制御するかです。SLOは、いつ出荷を続け、いつ止めるかを決めます。

時刻は03:12です。PagerDutyが「チェックアウトのレイテンシが上昇しています」と通知してきます。ダッシュボードを開くと、40分前からp99の線が少しずつ上がり続けています。どこまでのレイテンシなら許容できるのかを誰も書き留めていなかったので、それが問題なのかを誰も断言できません。そこから始まる通話上の議論、片目でSlackを追いながらの押し問答こそ、SLOがないことの代償です。

![夜の寝室のベッドサイドテーブルで光るスマートフォン。オンコールのアラート中](https://fdzlnqpwsaniezitwiuw.supabase.co/storage/v1/object/public/cms-media/upstreamapi/2026-11/da5f84-i1.webp)

## SLI、SLO、SLA：3つの言葉と3人の責任者

これらは混同されがちです。同じものではありません。混同すると、守れない契約を結んでしまうチームが出てきます。

- 
**SLI（サービスレベル指標）** は測定値です。妥当なイベントに対する良好なイベントの比率です。例えば、800ミリ秒未満で2xxを返したリクエストを、処理すべきリクエストの総数で割った値です。

- 
**SLO（サービスレベル目標）** は、その比率に対する一定期間の目標です。30日間で99.9%です。

- 
**SLA（サービスレベル契約）** は顧客との契約で、未達の場合は金銭的な補償が伴います。SLAは必ずSLOより緩く設定されます。SLAが99.9%でSLOも99.9%だと、補償を支払う前に問題を察知する余地が残りません。

[Google SRE書籍のサービスレベル目標の章](https://sre.google/sre-book/service-level-objectives/)も同じ線引きをしています。SLOは、外部に約束するどの数値よりも厳しい内部目標です。SLIとSLOはエンジニアが所有し、SLAはプロダクトチームと法務が所有します。

すでに収集しているメトリクスすべてに、4つ目の言葉を付け足す必要はありません。CPU、メモリ、キューの深さはデバッグには有用です。しかし顧客が直接体験するものではないので、SLIにはなりません。

## 実践でよいSLIとはどんなものか

よいSLIは比率であり、可能な限りユーザーに近い場所で測定され、何を「良好」とするかが明確に定義されています。

リクエスト駆動型のサービスでは、デフォルトとして2つのSLIを用意します。可用性（妥当なリクエストのうち5xxでないもの）とレイテンシ（妥当なリクエストのうち閾値以下のもの）です。平均ではなく閾値を使ってください。平均は裾野の遅いリクエストを隠してしまい、サポートチケットの多くは、その裾野から来るからです。

測定はサービスの内側ではなく、ロードバランサーやエッジで行ってください。起動時にクラッシュするサービスは、受け取らなかったリクエストについては完璧なエラー率を報告します。サーバー側のメトリクスはこの障害に対して盲目であり、ユーザーからは障害として見えます。

除外対象も明示してください。ヘルスチェック、自社監視による合成プローブ、不正な入力が原因の4xx応答は、通常SLOの対象外にすべきです。除外ルールはSLOのすぐ隣に書き留めておきます。インシデントレビューで数字が議論になったとき、議論すべきなのは定義であって、ダッシュボードが偶然示している値ではありません。

## 9の数を決める前に誰もやらない計算

9が1つ増えるたびに、許容されるダウンタイムは10分の1になります。ドキュメントに残すべき表はこれです。

- 
**99%**（30日間）：エラーバジェット1%、全停止を許容できるのは7.2時間。

- 
**99.9%**：バジェット0.1%、43.2分。

- 
**99.95%**：バジェット0.05%、21.6分。

- 
**99.99%**：バジェット0.01%、4.32分。

最後の行をもう一度読んでください。99.99%では、検知に5分かかり、切り戻しにも時間がかかる不具合1件で、その月のバジェットは吹き飛びます。人間がページに応答し、ノートPCを開いて4分未満で切り戻すことはできません。つまりこの目標は、バジェットが尽きる前に展開を止める自動化ゲートがあってはじめて到達可能です。

だから、サービスが本当に必要とする数字を選んでください。社内APIの多くは99.9%で問題なく動きます。決済の経路なら、より高い数字が正当化されるかもしれません。毎晩走るバッチジョブなら99%で足りることもあります。99.99%が「本格的に聞こえる」という理由で選ばれると、そのチームは配置できないオンコールローテーションに署名することになります。

![砂がほとんど落ちきった砂時計。エラーバジェットの象徴](https://fdzlnqpwsaniezitwiuw.supabase.co/storage/v1/object/public/cms-media/upstreamapi/2026-11/a422c2-i2.webp)

## エラーバジェットこそが要点であり、SLOそのものではない

99.9%のSLOは、0.1%の時間失敗することを許されているという意味です。その0.1%がエラーバジェットであり、この分野で最も有用な考え方です。

バジェットは議論を数字に変えます。プロダクトチームはリスクの高いマイグレーションを出したい。SREは危険だと言う。バジェットがなければ、それは意見対意見になり、勝つのは年功です。バジェットがあれば、問いは「残りはどれだけか、今回の変更でどれだけ消費しそうか」になります。

ルールは2つで十分に機能します。

- 
**バジェットが残っていれば出荷する。** リスクを取ることが許されているので、取ればよい。バジェットを一度も使わないチームは、ユーザーが求めていない信頼性に過剰投資しています。

- 
**バジェットが尽きたら凍結する。** 信頼性の作業でSLIが目標を回復するまで、機能開発を止めます。ただしこれは、最初のインシデントより前に経営陣が合意していた場合にだけ機能します。インシデントの最中に決めるのでは遅すぎます。

この2つ目のルールが事前に合意されていないなら、それはSLOではありません。緑と赤のゾーンがあるダッシュボードにすぎません。

## SLIそのものではなく、バーンレートで警告する

ここで最初の試みの多くが失敗します。「可用性が99.9%を下回ったらアラート」という設定です。アラートは被害が出た後に鳴るか、小さな揺らぎのたびに鳴るか、その両方になります。

よりよいシグナルは**バーンレート**です。バジェットがどれくらいの速さで消費されているかを、ウィンドウの終わりにちょうどバジェットがゼロになるペースと比べたものです。バーンレート1なら、その月をバジェットゼロで終えることを意味します。バーンレート14.4なら、その月のバジェットを約2日で使い切る軌道です。

[Google SRE Workbookのアラート設計の章](https://sre.google/workbook/alerting-on-slos/)は、長いウィンドウと短いウィンドウを組み合わせることを推奨しています。アラートが有意であり、かつ今も続いていることを確認するためです。30日間のSLOなら、最初に用意するページ条件として次の2つが妥当な出発点です。

- 
バーンレート14.4を1時間で観測し、5分で確認：月間バジェットの2%を消費します。誰かをページします。

- 
バーンレート6を6時間で観測し、30分で確認：月間バジェットの5%を消費します。誰かをページします。

計算は単純です。30日のウィンドウは720時間です。14.4倍のペースで1時間燃やせば、14.4 / 720 = 2%のバジェットを使うことになります。短いウィンドウがあるおかげで、問題がすでに終わった1時間後にアラートが鳴り続けることを防げます。

最初のルールを、エラー率をウィンドウごとに記録している前提でPrometheusのアラートとして書くと次のとおりです。

`groups:
  - name: checkout-slo-burn
    rules:
      - alert: CheckoutErrorBudgetFastBurn
        expr: |
          job:checkout_error_ratio:rate1h > (14.4 * 0.001)
          and
          job:checkout_error_ratio:rate5m > (14.4 * 0.001)
        labels:
          severity: page
        annotations:
          summary: "チェックアウトが30日間のエラーバジェットを1時間あたり2%消費しています"`0.001は99.9%のSLOにおける許容エラー率です。目標値を変えたら、この定数も一緒に変えてください。1か所にまとめておかないと、アラートとSLOが知らないうちにずれていきます。

ゆっくりした消費にページは不要です。3日間持続するバーンレート1は、翌営業日の朝に確認するチケットで十分です。ゆっくりした漏れのために人を起こしていると、オンコールのチームはページャーを無視することを覚えてしまいます。

![サーバーラックとステータスランプが並ぶデータセンターの通路](https://fdzlnqpwsaniezitwiuw.supabase.co/storage/v1/object/public/cms-media/upstreamapi/2026-11/f23ee5-i3.webp)

## 2つ目のプラットフォームを買わずにSLIを計算する場所

SLO専用の製品がなくても始められます。必要なのは、良好イベントのカウンター、全イベントのカウンター、そしてそれを30日間保存しておく場所だけです。

メトリクスがすでにホスト型のプラットフォームにあるなら、SLO機能は多くの場合、すでに支払っているデータの薄いレイヤーにすぎません。

Datadogはバーンレートアラート付きのSLOをネイティブに備えており、トレースとメトリクスがすでにそこにあるなら、最も手軽な道です。注意すべきは料金です。カスタムメトリクスと高カーディナリティのタグは急速に増えるので、コミットする前にSLIの系列の価格を確認してください。

Prometheusを運用しているなら、Grafanaが記録ルールとSLO関連のツールを通じて同じ領域をカバーします。その代わり、セットアップと自分の時間がより多く必要です。

率直な比較は、最初の有用なアラートまでの時間と、規模が大きくなったときのコストの対比です。最初の点ではDatadogが勝ち、2つ目の点ではPrometheusとGrafanaの組み合わせがたいてい勝ちます。チームに不足しているもので選んでください。

## SLOをロールアウトにつなぐ：多くのチームが飛ばす部分

レポートを生むだけのSLOは、半分しか使われていません。振る舞いを変えるのは、バジェットをデプロイ経路に組み込み、リリースが自分で止まるようにすることです。

SLOゲート付きの段階的ロールアウトは次のように動きます。フラグの背後で、まずトラフィックの1%に出します。そのコホートのSLIをベースラインと比べて監視します。カナリアコホートのバーンレートが閾値を超えたら、自動で切り戻します。問題がなければ5%、25%、100%と段階的に広げます。

これは、03:12に誰かがダッシュボードを見ていることを期待するのとは違います。03:12には、考えたくはないものです。欲しいのはボタン、できれば、ボタンすら要らないことです。

ここでフラグシステムが役に立ちます。フラグを使えば、切り戻しは10分かかる再デプロイではなく、数秒で終わる設定変更になります。

LaunchDarklyやそれに類するプラットフォームは、パーセンテージロールアウトとキルスイッチを提供します。ただ、多くは判断そのものをあなたに任せています。どのSLIを読むか、どの閾値を悪いとみなすか、誰が上書きできるかです。その隙間を埋めるのが、SLOに基づく自動切り戻しを備えた自動パイロットであり、upstreamapiが取るアプローチです。SDKの広さやエンタープライズ向けの制御では、LaunchDarklyが勝っています。それは認めておきます。

ゲートの形をTypeScriptで示します。どのフラグシステムを使うにせよ、判断ロジックは自分で書く価値のある部分です。

`type Cohort = { good: number; total: number };

const SLO_TARGET = 0.999;
const BUDGET = 1 - SLO_TARGET; // 0.001
const PAGE_BURN_RATE = 14.4;

function burnRate(c: Cohort): number {
  if (c.total === 0) return 0;
  const errorRatio = 1 - c.good / c.total;
  return errorRatio / BUDGET;
}

export function rolloutDecision(canary: Cohort): "advance" | "hold" | "revert" {
  if (canary.total < 500) return "hold"; // 判断するにはトラフィックが足りない
  return burnRate(canary) > PAGE_BURN_RATE ? "revert" : "advance";
}``hold`の分岐に注目してください。静かなサービスの1%カナリアでは、10分間に40件のリクエストしか来ないことがあります。そのうち1件のエラーは2.5%のエラー率になります。最小サンプルがなければ、ゲートはノイズで切り戻してしまい、チームはやがてそれを信用しなくなります。

## 80人規模のチームで繰り返し見る失敗

同じ数種類の失敗が、チームを横断して何度も現れます。そのほとんどは技術的な問題ではありません。

**SLOが多すぎる。** サービスごとに20の目標があると、誰も一つも覚えていません。ユーザーの1つのジャーニーにつき2〜3あれば十分です。

**誰も合意していないSLO。** エンジニアが週末に1人で書き上げる。プロダクトチームは一度も見ていないので、バジェットのポリシーは、最初に「ノー」と言った瞬間に崩れます。

**現在の性能に合わせて設定したSLO。** サービスが今日99.97%で動いているなら、目標を99.97%に設定すると、バジェットは残らず、必ず未達になります。ユーザーが不満を感じ始める水準に置いてください。それはほぼ常に、今の数字より低い位置です。

**SLOを永続的なものとして扱う。** 数字は四半期ごとに見直してください。バジェットを一度も使わないなら、目標を引き上げるか、より速く出荷します。毎月使い切っているなら、システムを直すか、目標が幻想だったと認めてください。

**感じられることではなく、数えやすいことを数える。** 空のカートを伴う200応答は、ログの上では成功ですが、顧客にとっては失敗です。「良好」の定義はユーザーの側から行ってください。

## 今週最初の1つは誰が書くか

プログラムを立ち上げる必要はありません。CEOが壊れたら誰かを呼び出させるであろう1つのジャーニーを選んでください。それに対して、可用性のSLIとレイテンシのSLIを1つずつ定義します。最初の四半期は目標を99.9%に設定し、凍結ポリシーを2文で書き、プロダクトチームに「合意」と書面で返信させます。

それから、バーンレートのアラートと、チーム全員が見られる場所に残りのバジェットを表示する場所を用意します。

フルプラットフォームに踏み切る前に、軽量な出発点が欲しいなら、Better Stackは稼働監視とインシデントのページングをもっと小さな構成で扱えます。ただし、バジェットの計算は付いてきません。

最初のバージョンは間違っているでしょう。それで構いません。大事なのは、次のインシデントレビューが、あらかじめ書き留めた数字から始まることです。感覚からではなく。

## 03:12はいま、どう見えるか

直近のチームのインシデントを思い出してください。それが問題かどうかを示す数字は、事前に書かれていましたか。正直に答えが「いいえ」なら、それが最初のSLOです。ポストモーテムがすでに、何を測るべきかを教えてくれています。

## FAQ

### SLO とは簡単に言うと何ですか？

一定期間にわたる特定のユーザー向け動作の信頼性目標です。例えば30日間でリクエストの99.9%が成功することを指します。どれだけの失敗を許容し、いつ出荷を止めるかをチームに伝えます。

### SLI、SLO、SLAの違いは何ですか？

SLIは測定値、SLOはその内部目標、SLAは顧客との契約で未達時に補償が伴います。SLAは通常SLOより緩く設定します。

### エラーバジェットとは何ですか？

目標と100%の差です。99.9%のSLOなら0.1%が許容される失敗の割合になります。バジェットが残っていれば出荷し、尽きたら機能開発を凍結します。

### 99.9%と99.99%はどれくらい違いますか？

30日間で99.9%は約43.2分、99.99%は約4.32分の全停止を許容します。9が1つ増えるごとに許容量は10分の1になります。

### バーンレートとは何ですか？

バジェットを消費する速さを、ウィンドウ終了時にちょうどゼロになるペースと比べた値です。バーンレート1なら月末にバジェットがゼロになります。

### 最初のSLOはどう始めればよいですか？

最も重要なユーザージャーニーを1つ選び、可用性とレイテンシのSLIを1つずつ定義します。目標は99.9%から始め、凍結ポリシーを書面で合意します。