SLO / Error Budget — Parky

Parky の API / Mobile / Web に対する Service Level Objective (SLO) と error budget の定義・運用ルール。 2026-04-28 初版。観測性配線 (Sentry/OTel/CAE) の本格運用と同時に開始する。 2026-04-30 改訂 (監査 M-3): 立ち上げ期と本格運用期で 段階的目標 を導入。

設計方針

  • 目的: ユーザー影響の継続観測と「いつリリースを止めるべきか」を客観的に決める基準。
  • 対象: api.parky.co.jp (Workers BFF) を一次対象。Mobile / Web ポータルは Phase 2 で追加。
  • 計測ソース: Cloudflare Analytics Engine (CAE) + Sentry + Workers Observability。Logpush → R2 を 30 日 retention で raw データ保管。
  • : 28 日ローリング (4 週)。週次レビューで burn rate を確認する。
  • error budget: (1 - SLO%) × 28 日のリクエスト総数 の許容失敗数。
  • alert 方針: burn rate × 14.4 (1h で 24h 分消費) と × 6 (6h で 1日分消費) の二段アラート。

段階的目標の考え方 (Phase 1 / Phase 2)

監査 (2026-04-29) は本来「5xx error rate < 0.1% / P99 < 500ms」(= 99.9% / P99) を要求。 ただし Parky は 2026-03 末開始・1 人開発・Phase 1 (MAU 1万 + IMP 100万) の立ち上げ段階で、 インフラと観測性が安定する前から 99.9% を契約してしまうと、健全な実験速度が損なわれる (error budget が常時枯渇 → freeze 連発 → 出荷不能)。

そのため SLO は 段階的に引き上げる

Phase 期間目安 可用性 レイテンシ 採用根拠
Phase 1 (立ち上げ) 〜MAU 1万到達 (2026-06〜2026-12 想定) 99.5% (5xx < 0.5%) p95 < 500ms 1 人開発 / Cloudflare Free〜Pro / 観測整備中。実験速度を確保しつつユーザー影響を一定以下に保つ。
Phase 2 (本格運用) MAU 1万到達後、または Phase 2 (ARR 1億) 入り 99.9% (5xx < 0.1%) p99 < 500ms 監査要求準拠。Cloudflare Pro+ Health Checks、Sentry quota 拡張、オンコール rota 整備が前提。

Phase 移行の判定: 直近 4 週連続で Phase 2 値 (99.9% / p99 < 500ms) を達成し、 かつ次の運用要件が満たされた時点で Phase 2 SLO を契約として宣言する。

  • Cloudflare Health Checks (Pro 以上, 1 分粒度) 稼働
  • Sentry burn rate 二段アラート (14.4× / 6×) 稼働
  • 週次 SLO レビューが 4 週以上継続
  • オンコール rota またはそれに類する 1 次受け体制が文書化済

Phase 1 中は監査要求 (99.9%) を 観測目標 (informational) として CAE で並走計測し、 Phase 2 移行の判断材料に使う (= 実力が先、契約が後)。

API SLO (Tier 0 — Workers BFF)

Phase 1 (現行・契約値)

指標 目標値 計測 error budget (28 日)
可用性 (success rate) 99.5% CAE: 5xx を除く 2xx/3xx/4xx の割合 0.5% (例: 100 万 req/月 なら 5,000 req まで)
レイテンシ p95 < 500ms CAE: status < 500 のみで集計 p95 が 500ms を超えた時間の割合 ≤ 5%
レイテンシ p99 < 1500ms CAE: 同上 同上 ≤ 5%
エラー率 < 0.5% Sentry + CAE 5xx 0.5% を 28 日連続で超過したら freeze

Phase 2 (将来契約値・現在は観測目標)

指標 目標値 計測 error budget (28 日)
可用性 (success rate) 99.9% CAE: 5xx を除く 2xx/3xx/4xx の割合 0.1% (例: 100 万 req/月 なら 1,000 req まで)
レイテンシ p95 < 300ms CAE: status < 500 のみで集計 p95 が 300ms を超えた時間の割合 ≤ 5%
レイテンシ p99 < 500ms CAE: 同上 同上 ≤ 5%
エラー率 < 0.1% Sentry + CAE 5xx 0.1% を 28 日連続で超過したら freeze

除外 (SLI から除く)

  • 4xx クライアントエラー全般 (401 / 403 / 404 / 409 / 422 / 429) — クライアント由来
  • 計画メンテナンス時間中の 5xx (事前 announce + Discord 通知必須)
  • 上流 (Supabase / Cloudflare 自身) の同時刻インシデント中 (Cloudflare Status / Supabase Status で確認)

Mobile SLO (Phase 2)

指標 目標値 計測
crash-free sessions ≥ 99.5% Sentry Flutter
cold start p95 < 2.5s Firebase Performance Monitoring (要設定)
検索 RPC p95 < 300ms CAE で endpoint 別
OTA バージョン採用率 7 日 ≥ 80% App Store / Play Store consoles

Web Portal SLO (Phase 2)

指標 目標値
LCP p75 < 2.5s (CrUX 月次)
CLS p75 < 0.1
JS error rate < 1% of pageviews (Sentry browser SDK)

Error Budget 運用ルール

状態判定

budget_total     = (1 - SLO_target) × total_requests_28d
budget_remaining = budget_total - errors_consumed_28d
burn_rate_1h     = errors_last_1h / (budget_total / (28 × 24))   # 1h 想定消費
burn_rate_6h     = errors_last_6h / (budget_total / (28 × 4))    # 6h 想定消費
状態 条件 アクション
健康 (green) budget_remaining > 50% 通常開発
注意 (yellow) budget_remaining 25-50% 高リスク変更を要レビュー
危険 (orange) budget_remaining 10-25% new feature freeze、信頼性改善のみ
枯渇 (red) budget_remaining < 10% deploy freeze、postmortem 必須

Burn rate アラート (Phase 1 — 99.5% 想定)

SLO target = 0.995 → 許容エラー率 = 0.005。

条件 意味 error rate しきい値 通知先
burn_rate_1h × 14.4 1 時間で 1 日分消費 (fast burn) 5xx rate > 7.2% (= 0.005 × 14.4) Discord #p0-alerts (P1)
burn_rate_6h × 6 6 時間で 1 日分消費 (slow burn) 5xx rate > 3.0% (= 0.005 × 6) Discord #p0-alerts (P2)
budget < 25% budget 危険 Discord #p1-ops (Daily summary)

Burn rate アラート (Phase 2 — 99.9% 想定)

SLO target = 0.999 → 許容エラー率 = 0.001。

条件 意味 error rate しきい値 通知先
burn_rate_1h × 14.4 1 時間で 1 日分消費 (fast burn) 5xx rate > 1.44% (= 0.001 × 14.4) Discord #p0-alerts (P0/P1)
burn_rate_6h × 6 6 時間で 1 日分消費 (slow burn) 5xx rate > 0.6% (= 0.001 × 6) Discord #p0-alerts (P2)
budget < 25% budget 危険 Discord #p1-ops (Daily summary)

Phase 2 のしきい値は sentry-alert-rules.md R-02failure_rate() > 0.0144 と一致 (= 99.9% target × 14.4×)。 Phase 1 中は同 rule を dev/prod の自然 5xx 率では発火しない 安全網として併用し、 Phase 1 専用の > 0.072 rule を別途登録する (M-04 manual checklist)。

週次レビュー (毎週月曜)

  • 28 日 budget 残量
  • 当週の SEV1/2 件数 + RCA 進捗
  • 翌週の planned change リスク評価
  • 直近 4 週の SLO trend (改善 / 悪化)
  • Phase 2 観測目標 (99.9% / p99 < 500ms) の達成状況 ← Phase 1 中の追加項目

アクションランブック (5xx 急増時)

burn rate alert (Discord #p0-alerts) が発火したら、以下を順に実行する。 詳細トリアージは incident-response.md §トリアージ を参照。

Step 1 — 5 分以内: 一次トリアージ

  1. Discord alert の embed から 影響範囲 (api/admin/owner/marketing/home) と 5xx 率 を確認
  2. Cloudflare Workers Observabilityparky-api-prod の Logs/Metrics タブを開く
  3. wrangler tail --config wrangler.<worker>.toml --env prod で直近のエラーパターンを確認 (4 split worker のうち該当を選ぶ — 例: 5xx burst の channel が判別済なら wrangler.public.toml 等)
    cd parky/api && npx wrangler tail --config wrangler.public.toml --env prod --format pretty | head -100
    
  4. synthetic-healthcheck.md/healthz 失敗有無を確認 (= 全停止か部分障害か切り分け)

Step 2 — 15 分以内: 上流確認 + 初動

  1. 上流ステータス確認:
  2. 直前 deploy の特定:
    gh run list --workflow deploy-api-prod.yml --limit 5
    
    直近 1 時間以内に deploy があれば rollback を最優先 (deployment-rollback.md)
  3. error の主因特定 (Sentry):
    • Sentry parky-api プロジェクトの Issues タブで直近 1h を確認
    • 同一 error が 80% 以上を占めるなら原因コード特定 → hotfix
    • 散発なら infra 起因の可能性 (Supabase connection pool / R2 / KV)

Step 3 — 1 時間以内: 緩和か rollback 判断

状況 アクション
直前 deploy が原因 rollback (deployment-rollback.md) — 議論せず即実行
上流 (Supabase/CF) 障害 上流復旧待ち + status page 監視 + ユーザー告知判断
既知 bug の負荷増幅 rate limit / circuit breaker を一時的に強める (api/src/middleware/rate-limit.ts)
原因不明 + budget red deploy freeze 宣言 (#p1-ops) + tech-lead 召集

Step 4 — 24 時間以内: 事後

  1. SEV1/2 ならポストモーテム作成 (postmortem-template.md)
  2. 本 doc の SLO 値 / burn rate しきい値が現実に合っているか週次レビューで再評価
  3. 関連 alert rule (sentry-alert-rules.md) の感度調整
  4. error budget が枯渇 (red) した場合は postmortem の AI として 信頼性改善タスクを次週以降に必ず計上する

実装 TODO

Phase 0 (即日)

  • Sentry org 作成 + Workers/Flutter project 作成
  • Sentry DSN を wrangler secret put SENTRY_DSN で dev/prod 投入
  • Honeycomb 無料アカウント + OTLP endpoint 投入
  • Cloudflare Health Checks for /healthz (60s 間隔, Discord alert) — synthetic-healthcheck.md 本格化

Phase 1 (1 週間)

  • CAE で SLO 集計 SQL を確立 (analytics-engine.md に追記)
  • 週次 cron で error budget 残量を Discord に投稿
  • burn rate alert (Phase 1: 7.2% / 3.0%) を Sentry rule で配線 — sentry-alert-rules.md
  • Phase 2 観測目標 (99.9% / p99) の並走計測を CAE で開始
  • 本 doc の SLO 値を 1 ヶ月運用後に再校正

Phase 2 (MAU 1万到達後)

  • Phase 2 SLO (99.9% / p99 < 500ms) を契約値として正式採用
  • burn rate alert を Phase 2 値 (1.44% / 0.6%) に切り替え
  • Mobile crash-free + cold start を Sentry/Firebase で計測開始
  • Web Portal LCP/CLS を Sentry browser SDK で計測開始
  • Status page 公開 (オプション、parky.statuspage.io 等)
  • オンコール rota 文書化 (incident-response.md TODO 反映)

参照

↗ Source markdown (slo-error-budget.md)