SLO・SLI・エラーバジェット入門|「どこまで落ちてよいか」を数値で決める運用設計

kento_morota 12分で読めます
社内のAI・IT活用、技術がわかる相手に無料相談。 相談 →
目次

「障害が起きるたびに『二度と起こすな』と言われるが、ゼロにはできない」「アラートが鳴りすぎて誰も見なくなった」「新機能のリリースと安定運用、どちらを優先すべきか毎回もめる」――こうした悩みは、「どこまで落ちてよいか」がチームで数値として合意されていないことから生まれます。

この記事では、SLA・SLO・SLIという似た3つの言葉の違いを整理したうえで、可用性とレイテンシを測るSLIの具体的な作り方、ユーザー視点でSLOの数値を決める手順、エラーバジェットを使って機能開発と信頼性のバランスを取る考え方、そしてバーンレートアラートで「本当に対応が必要なとき」だけ通知を受ける方法を解説します。SREという役割そのものの説明はSREとは?DevOpsとの違いに、顧客向けのSLA文書の書き方はSLAとは?意味・書き方・具体例に譲り、本記事は内部の運用設計に絞ります。

SLA・SLO・SLIの違いを一言で

用語意味誰のためのもの
SLI(Service Level Indicator)サービスの品質を測る「指標」そのもの運用チーム成功レスポンスの割合、500ms以内に返ったリクエストの割合
SLO(Service Level Objective)SLIに対して設定する内部の「目標値」開発・運用チーム30日間で成功率99.9%以上
SLA(Service Level Agreement)顧客と結ぶ「契約」。未達なら返金などのペナルティ顧客・営業・法務月間稼働率99.5%を下回った場合は利用料の10%を返金

関係としては「SLIを測り、SLOを目標にし、SLAはSLOより緩く約束する」が基本です。SLAをSLOと同じ値にすると、内部目標を少し外しただけで契約違反になります。SLOはSLAより厳しく設定し、SLOを守っていれば自然にSLAも守れる、という余裕を持たせます。SLAを結んでいない自社サービスでも、SLOとSLIは「自分たちがどこまでを正常とみなすか」を決めるために必要です。

SLIの作り方:可用性とレイテンシを「割合」で測る

SLIは「良いイベント÷全イベント」の形にする

SLIは「サーバーが生きているか」ではなく、ユーザーが体験した結果を「良かった割合」として表現します。形は常に次のとおりです。

SLI = 良いイベントの数 ÷ 対象イベントの総数

この形にしておくと、可用性もレイテンシも同じ土俵で扱え、後述のエラーバジェットの計算も統一できます。

可用性SLIの例

Webアプリなら「ロードバランサーが受けたリクエストのうち、5xx以外を返した割合」が最も素直な可用性SLIです。サーバーの死活監視(pingが通るか)ではなく、実際のリクエストを分母にするのがポイントです。ユーザーが誰もアクセスしていない深夜にサーバーが5分止まっても、リクエストベースのSLIでは影響がほぼゼロになり、ユーザーの体験に近い値になります。

注意点として、4xxは原則「ユーザー側の問題」として分母から除くか良いイベントに含めますが、認証エラー(401)が急増したらそれは自社の障害かもしれません。何を「悪いイベント」にするかは、ユーザーが困ったかどうかで決めます。

レイテンシSLIの例

レイテンシは「平均応答時間」ではなく、「閾値以内に返ったリクエストの割合」で定義します。平均は少数の極端に遅いリクエストに引きずられ、逆に多数の遅いリクエストが平均には出ないこともあるからです。「500ms以内に返ったリクエストの割合が99%以上」という形なら、ユーザーの100人に1人だけが遅さを感じる、と直感的に説明できます。

実際にPrometheusでSLIを計算する例を示します。メトリクスの収集方法は監視とオブザーバビリティ入門を参照してください。

# 可用性SLI(直近30日、5xx以外の割合)
sum(rate(http_requests_total{job="api",code!~"5.."}[30d]))
/
sum(rate(http_requests_total{job="api"}[30d]))

# レイテンシSLI(直近30日、500ms以内に返った割合)
sum(rate(http_request_duration_seconds_bucket{job="api",le="0.5"}[30d]))
/
sum(rate(http_request_duration_seconds_count{job="api"}[30d]))

SLOの決め方:ユーザー視点で「十分」を探す

高ければよいわけではない

SLOは99.99%を目指すほど偉いわけではありません。9が1つ増えるごとに、許容できる停止時間は約10分の1になり、必要な冗長化・自動化・人員のコストは桁で増えます。99.9%は30日で約43分、99.99%は約4分の停止しか許されません。深夜に1回再起動しただけで使い切る値です。可用性の数字と冗長化の関係は可用性99.9%は年間何時間の停止?で詳しく扱っています。

決める手順

  1. ユーザーの重要な操作(クリティカルユーザージャーニー)を3〜5個選ぶ。「ログイン」「商品検索」「決済」のように、止まると業務やビジネスに直接響く操作です。全エンドポイントを対象にすると、重要でない管理画面の遅さで予算を消費してしまいます。
  2. 操作ごとにSLIを定義する。可用性とレイテンシの2つを基本に、必要なら「バッチが期限内に完了した割合」などを加えます。
  3. 過去のデータで現状の値を測る。現状が99.7%なら、いきなり99.99%を掲げても達成できません。まず現状より少し高い値を仮置きします。
  4. 「ユーザーが離れる限界」を事業側と話す。決済は99.95%、検索は99.9%、レポート画面は99%、のように操作の重要度で差をつけて構いません。
  5. 期間(ウィンドウ)を決める。30日のローリングウィンドウが一般的です。四半期ごとに見直します。

エラーバジェット:開発速度と信頼性のバランスを数値で決める

「落ちてよい量」を予算として扱う

SLOが99.9%なら、残りの0.1%は「失敗してよい割合」です。これがエラーバジェットです。30日で100万リクエストがあるなら、1,000リクエストの失敗までは目標の範囲内です。この考え方の効果は、「障害ゼロを目指す」という達成不可能な目標を、「予算内に収める」という管理可能な目標に置き換えることにあります。

予算の残量でリリース判断を変える

エラーバジェットは、機能開発と信頼性改善の優先順位を決めるルールとして機能します。

  • 予算が十分残っている:積極的にリリースしてよい。少々のリスクを取って新機能を出す。カナリアリリースの割合を上げるなど、攻めの判断ができる。
  • 予算を使い切った(または使い切りそう):新機能のリリースを止め、信頼性改善(テスト強化、監視追加、技術的負債の解消)に開発リソースを振り向ける。予算が回復するまで続ける。

このルールを事前に開発・運用・事業側で合意しておくことで、障害のたびに「誰が悪いか」「リリースを止めるべきか」を感情で議論しなくて済みます。エラーバジェットは開発チームを縛るためではなく、「ここまでは自由にやってよい」と保証するための仕組みです。

# エラーバジェット残量(30日ウィンドウ、SLO 99.9%の場合)
# 1 - (実際のエラー率 / 許容エラー率) が残量の割合
1 - (
  (1 - (
    sum(rate(http_requests_total{job="api",code!~"5.."}[30d]))
    / sum(rate(http_requests_total{job="api"}[30d]))
  ))
  / (1 - 0.999)
)

バーンレートアラート:閾値ではなく「消費速度」で通知する

「エラー率が1%を超えたら通知」の問題

従来のアラートは「エラー率が閾値を超えたら通知」でした。しかし閾値を低くすれば一時的な揺らぎで鳴り続け、高くすれば小さな障害を見逃します。また「深夜に3分間だけ5%のエラー」と「1日中ずっと0.2%のエラー」のどちらが深刻かを閾値では表せません。

バーンレート=予算の消費速度

バーンレートは「このペースでエラーが続くと、予算をウィンドウ期間の何倍の速さで使い切るか」を表す倍率です。バーンレート1なら、30日でちょうど予算を使い切る速さ。バーンレート14.4なら、約2日で使い切る速さです。SLOが99.9%の場合、許容エラー率は0.1%なので、バーンレート14.4は「エラー率1.44%」に相当します。

実務では、複数の時間窓を組み合わせた「マルチウィンドウ・マルチバーンレート」が推奨されています。

深刻度バーンレート長い窓短い窓予算消費対応
緊急(ページ)14.41時間5分1時間で予算の2%即時対応
緊急(ページ)66時間30分6時間で予算の5%即時対応
注意(チケット)13日6時間3日で予算の10%翌営業日に調査

「長い窓」で持続的な問題だけを拾い、「短い窓」で既に収まった問題でアラートが鳴り続けるのを防ぎます。両方の条件を満たしたときだけ通知します。

# Prometheusアラートルール:バーンレート14.4(1時間窓+5分窓)
groups:
  - name: slo-api-availability
    rules:
      - record: job:slo_errors_per_request:ratio_rate1h
        expr: |
          sum(rate(http_requests_total{job="api",code=~"5.."}[1h]))
          / sum(rate(http_requests_total{job="api"}[1h]))
      - record: job:slo_errors_per_request:ratio_rate5m
        expr: |
          sum(rate(http_requests_total{job="api",code=~"5.."}[5m]))
          / sum(rate(http_requests_total{job="api"}[5m]))
      - alert: ApiErrorBudgetBurnFast
        expr: |
          job:slo_errors_per_request:ratio_rate1h > (14.4 * 0.001)
          and
          job:slo_errors_per_request:ratio_rate5m > (14.4 * 0.001)
        for: 2m
        labels:
          severity: page
        annotations:
          summary: "API可用性SLOの予算を高速に消費中(バーンレート14.4超)"

小さなチームでの始め方

SLOの導入は、専任のSREがいなくても始められます。むしろ少人数のチームこそ、アラートを減らして睡眠を守るために効果があります。

  1. 最重要の操作を1つ選ぶ。多くの場合「トップページまたはログインが表示される」で十分です。
  2. ロードバランサーのメトリクスでSLIを作る。ALBならCloudWatchのHTTPCode_Target_5XX_CountRequestCountから計算できます(AWS CloudWatchで監視・アラート設定)。アプリ側の計装は後回しでよい。
  3. 過去1か月の値を見て、少し高めのSLOを仮置きする。99.5%でも構いません。
  4. 既存の閾値アラートを1つバーンレートアラートに置き換える。全部一度に変える必要はありません。
  5. 月に1回、SLOの達成状況と予算の残量を振り返る。障害があった月はポストモーテムと一緒に見直します。

トラブル事例:アラート疲れで本当の障害を見逃した

症状

「エラー率が0.5%を超えたら通知」というアラートを設定して半年。毎日数回、数分間だけ鳴っては自然に収まるため、チームは通知を見ずに閉じる習慣がついていました。ある日、決済APIが実際に30%のエラーを返す障害が起きましたが、いつもの通知と区別がつかず、対応開始までに2時間かかりました。

原因

閾値アラートが「深刻度」を表現できていませんでした。0.5%を数分超えるだけの揺らぎと、30%が持続する障害が、同じ通知として届いていたのです。またアラートの対象が「全エンドポイント」だったため、重要でない管理画面のエラーでも鳴っており、通知の信頼性がゼロになっていました。

対処

  1. 決済・ログイン・商品検索の3操作にSLIを絞り、それぞれにSLO(99.95%/99.9%/99.9%)を設定した。
  2. 閾値アラートを廃止し、バーンレート14.4(1時間+5分)と6(6時間+30分)をページ通知、1(3日+6時間)をチケット起票に置き換えた。
  3. 結果として、ページ通知は月に数回以下に減り、鳴ったときは必ず対応が必要という状態になった。

アラートの数を減らすことは、監視を弱めることではありません。「鳴ったら動く」という信頼を取り戻すことです。

まとめ

SLIは「良いイベントの割合」、SLOはその内部目標、SLAは顧客との契約であり、SLOはSLAより厳しく設定します。SLIはユーザーの重要な操作を対象に、可用性は「5xx以外の割合」、レイテンシは「閾値以内に返った割合」として定義し、SLOは現状のデータと事業上の「十分」から決めます。SLOの残り、つまりエラーバジェットを機能開発と信頼性改善の優先順位を決めるルールにし、アラートは閾値ではなくバーンレートで「予算を早く消費しているときだけ」通知する。この一連の仕組みが、障害をゼロにするのではなく「許容範囲に管理する」運用の土台になります。

SLOの設計やアラートの整理、監視基盤の見直しでお困りの場合は、Harmonic Societyのシステム開発・インフラ支援にご相談ください。

#SLO#SLI#エラーバジェット#SRE

Harmonic Society

この記事の内容、自社の業務でも活かせそうですか?

ローカルLLM・AI・クラウドなどの技術導入を、要件整理からPoC・社内展開まで代表エンジニアが伴走します。オンライン対応・全国OK。まずは30分の無料相談から。売り込みはしません。

共有:
無料メルマガ

週1回、最新の技術記事をお届け

AI・クラウド・開発の最新記事を毎週月曜にメールでお届けします。登録は無料、いつでも解除できます。

プライバシーポリシーに基づき管理します

関連記事

Related / 9 articles

  1. プログラミング

    DDoS攻撃の仕組みと対策入門|レイヤー別の防御とCDN・クラウドの活用

    DDoS攻撃をボリューム型・プロトコル型・アプリ層に分けて仕組みを解説し、自前サーバーで防げない理由、CloudflareやAWS Shieldの標準防御、オリジンIPの隠し方、レートリミットとBot対策、攻撃を受けたときの初動、費用が跳ね上がるDenial of Walletへの備えまでわかります。

  2. プログラミング

    WAFとは?仕組み・導入パターン・誤検知対策|Webアプリを攻撃から守る実践ガイド

    WAFがファイアウォールやIDSと何が違うのか、シグネチャとマネージドルールの仕組み、Cloudflare WAF・AWS WAF・ModSecurityの比較、フォーム送信がブロックされる誤検知の調査と例外設定、ログ監視、WAFが代替できないことまで実践的に解説します。

  3. プログラミング

    セキュリティヘッダー入門|CSP・HSTS・X-Frame-Optionsの設定と効果を実践解説

    CSP・HSTS・X-Frame-Options・X-Content-Type-Optionsなど主要セキュリティヘッダーが防ぐ攻撃と、CSPのReport-Onlyからの段階導入、nonce/hash、HSTS preloadの不可逆リスク、Nginx・Next.js・Astroでの設定例、確認方法を解説します。

  4. プログラミング

    クラウドの通信費(Egress)入門|データ転送量課金の仕組みと転送コストを抑える設計

    クラウドの「受信無料・送信有料」の原則、AZ間・リージョン間・インターネット向けの単価差、NATゲートウェイ処理料の罠、CDNで転送量を減らす方法、バックアップやログ転送の見落とし、請求書で転送料を特定する手順を解説。想定外の請求を防げます。

  5. プログラミング

    秘密情報をGitに入れない仕組み|.gitignore・git-secrets・履歴から漏れた鍵の削除

    APIキーや.envをGitにコミットしてしまう典型経路と、.gitignore・.env.exampleの運用、pre-commitでのgitleaks検知、GitHub secret scanningの活用、漏れた鍵の無効化と履歴書き換え(git filter-repo)の手順を解説。仕組みで再発を防げます。

  6. プログラミング

    開発・ステージング・本番環境の分離設計|環境差分をなくす構成とアクセス制御

    開発・ステージング・本番それぞれの目的と、構成をコードで揃える方法、環境別の設定注入、本番データを使わないテストデータ戦略、ステージングの保護(Basic認証・IP制限・noindex)、コストを抑える運用までを解説。環境差分による本番障害を防げます。

  7. プログラミング

    ngrok・Cloudflare Tunnelでローカルを公開|Webhook開発とデモ環境の作り方

    NAT内のローカル環境にStripeやLINEのWebhookを届けるトンネリングの仕組みを解説。ngrok・Cloudflare Tunnel・localtunnelの比較、固定ドメインと認証、リクエスト検査、公開時のセキュリティ、自宅サーバー公開への応用までわかります。

  8. プログラミング

    ローカル開発環境のHTTPS化|mkcert・hostsファイル・自己署名証明書の正しい使い方

    ローカル開発をHTTPS前提にすべき理由(Secure Cookie・Service Worker・OAuth)と、mkcertでローカルCAを作りhostsで独自ドメインを割り当ててVite・Next.js・Dockerで使う手順を解説。証明書警告を無視する癖の危険も理解できます。

  9. プログラミング

    localhost・0.0.0.0・127.0.0.1の違い|ポートとUnixソケットを理解して「つながらない」を解決

    localhost・127.0.0.1・0.0.0.0の意味の違い、Dockerで外から接続できない原因、host.docker.internal、ポート競合の調べ方、Unixソケットの利点と権限、1024未満ポートの制約を解説。「つながらない」を仕組みから解決できます。

Harmonic Society

「読んで終わり」にせず、自社の業務で試してみませんか?

AI・ローカルLLM・クラウドの導入を、要件整理からPoC・社内展開まで代表エンジニアが伴走します。オンライン対応・全国OK・売り込みなし。

無料・30分・オンラインOK|1営業日以内に返信します