背景|MVP のままでは捌けなくなったアクセス増

ご相談をいただいたのは、シリーズ B 直後の BtoB SaaS を運営するクライアントでした。半年前に立ち上げた MVP がうまく PMF に届き、月間のアクティブ企業数が数か月で 5 倍以上に伸びたところで、平日の朝とレポート締め時間帯にレスポンスが目に見えて重くなっていたのです。具体的には、ダッシュボードの初期表示が普段の 0.8 秒から、ピーク時には 6 秒以上まで悪化し、一部のリクエストはタイムアウトでエラーになっていました。

MVP の設計は、当時の意思決定としては正しいものでした。1 台のアプリケーションサーバーに単一のリレーショナルデータベースをぶら下げ、画面ごとに必要なデータをその場で問い合わせる素直な構成です。検証段階では十分に速く、開発スピードも稼げます。しかし PMF を超えてアクセスが伸びると、この素直さがそのままボトルネックになります。

クライアント側の事情は次のようなものでした。

  • 既存顧客の利用が伸びている最中で、サービスを止めての作り替えはできない
  • 社内にインフラ専任のエンジニアがおらず、どこから手を付けるべきか判断できない
  • 投資家への次の報告までに、信頼性の指標を示せる状態にしたい

「止められない、原因が見えない、でも待てない」という、スケール期の SaaS によくある状況です。FIXIT はこれを AI 駆動開発 で段階的に解きほぐすことを提案し、6 週間・実工数 18 人日で、ピーク時のレスポンスを MVP 期と同水準まで戻し、想定アクセスの数倍まで耐える設計に移行しました。

なお、ゼロから短期間で SaaS の MVP を立ち上げる工程は別の事例 SaaS MVP を 3 週間で本番投入したスタートアップ案件 で扱っています。本記事はその「次のフェーズ」、つまり MVP が当たった後のスケール設計の話です。

ボトルネックの特定と優先順位づけ

スケール対応で最もやってはいけないのは、原因を特定する前にサーバーを増強することです。CPU やメモリを増やせば一時的に楽になるケースもありますが、本当の原因がデータベースのロック競合や N+1 クエリだった場合、コストだけが膨らんで問題は残ります。最初の 1 週間は、ひたすら計測に充てました。

まず Datadog の APM を本番に仕込み、トレースを 1 週間分ためました。そのうえで、トレースのサマリーと遅いエンドポイントのソースコードを Claude Code に読み込ませ、「どのリクエストが、どの処理で、どれだけ時間を使っているか」を構造化して洗い出しています。AI に計測データとコードの両方を同時に読ませると、人間が当たりを付けて 1 つずつ確認するより、はるかに早く全体像が見えます。

洗い出した結果、遅延の内訳はおおむね次のように分かれました。

ボトルネック全体の遅延に占める割合対応の難易度
N+1 クエリ (一覧・ダッシュボード)約 45%
集計クエリのフルスキャン約 25%
キャッシュ不在による同一クエリの連打約 20%
アプリサーバーの台数不足約 10%

ここで重要なのは、コストと効果の比で優先順位を付けることです。一覧画面の N+1 は対応難易度が低いわりに遅延の半分近くを占めていたため、最初のウェーブで潰すべき筆頭でした。逆に、アプリサーバーの増強は効果が読めても全体の 1 割程度。先に増強しても体感は変わらなかったはずで、計測なしで着手していたら判断を誤っていた典型例です。

Claude Code には、各ボトルネックについて「想定される改善幅」「副作用のリスク」「検証方法」をセットで出させ、人間がビジネス影響の大きさで並べ替えました。改善幅の数字そのものは AI の推定なので鵜呑みにはしませんが、検証の段取りまで一緒に出させると、議論のたたき台として非常に効率的です。

AI 駆動開発で進めたスケール設計の段階移行

優先順位が決まったら、リスクの低いものから順に、1 つずつ計測しながら手を入れていきます。全部をまとめて作り替える「ビッグバン移行」は、原因の切り分けができなくなるうえ、本番事故のときに切り戻し先を見失います。今回は 3 ウェーブに分け、各ウェーブの前後で必ず負荷テストを回す進め方を採りました。

データベースとキャッシュ層の再設計

最初のウェーブは、遅延の 7 割近くを占めていたデータベース周りです。

N+1 クエリは、原因箇所が特定できていれば AI が得意とする領域でした。Claude Code に「このエンドポイントの N+1 を、発行クエリ数が一定になるように直したうえで、修正前後でレスポンス内容が変わらないことを保証するテストも書いて」と依頼し、出力を人間がレビューする流れです。一覧系の 12 エンドポイントを直し、1 リクエストあたりのクエリ数が最大で 200 本以上から 5 本前後まで減りました。

集計クエリのフルスキャンには、複合インデックスの追加と、頻繁に参照される集計値の事前計算で対応しました。インデックスは闇雲に張ると書き込み性能を落とすため、実行計画を Claude Code に読ませ、どのインデックスがどのクエリに効き、書き込みにどの程度の負荷をかけるかを整理してから本番に適用しています。

キャッシュ層は、Redis を読み取り頻度の高いデータの前段に置きました。ここで重視したのはキャッシュの無効化設計です。スケール対応で生まれがちな事故は「速くなったが、古いデータが見える」というもので、これは負荷障害よりタチが悪い場合があります。更新イベントに連動してキーを無効化する仕組みをテストで担保し、TTL は安全側に短く設定して、まず正しさを確保してから少しずつ伸ばしました。

設計判断の根拠とコードの両方を同じ場で扱えるのが、AI 駆動でのインフラ作業の強みです。「なぜこの設計にしたか」をその場でドキュメント化させ、後からクライアント側のエンジニアが読んで運用を引き継げる状態を保ちました。テストを先に書いてから AI に実装させる進め方の詳細は AI 駆動 TDD - テストを AI に先に書かせる開発フロー で扱っています。

負荷テストで本番前にボトルネックを潰す

スケール設計は、本番のアクセスで初めて壊れるのが最悪のシナリオです。そうならないよう、各ウェーブの修正は必ず本番相当のステージング環境に対して k6 で負荷テストを掛けてから本番へ出しました。

シナリオ作成は、AI が効くポイントの 1 つです。本番のアクセスログから「どのエンドポイントが、どの比率で、どんな順序で叩かれているか」を抽出し、それを Claude Code に渡して k6 のシナリオに起こさせます。手書きだと現実離れした均等アクセスのシナリオになりがちですが、実ログを起点にすると、朝のログインが集中する波や、レポート締めで集計が一斉に走る山まで再現できます。

// load-test/dashboard.js
import { check, sleep } from "k6";
import http from "k6/http";
 
// 本番ログの比率を反映: ピーク時の同時接続を段階的に再現する
export const options = {
  stages: [
    { duration: "2m", target: 200 }, // 通常時相当まで立ち上げ
    { duration: "3m", target: 800 }, // ピーク時相当
    { duration: "3m", target: 1600 }, // 想定の数倍まで負荷を盛る
    { duration: "2m", target: 0 },
  ],
  thresholds: {
    http_req_duration: ["p(95)<1500"], // 95 パーセンタイルで 1.5 秒以内
    http_req_failed: ["rate<0.01"], // エラー率 1% 未満
  },
};
 
export default function () {
  const res = http.get(`${__ENV.BASE_URL}/api/dashboard/summary`);
  check(res, {
    "status is 200": (r) => r.status === 200,
    "body has metrics": (r) => r.body.includes("metrics"),
  });
  sleep(1);
}

このテストを各ウェーブで繰り返し、95 パーセンタイルのレスポンスとエラー率を閾値で監視しました。1 回目の負荷テストでは、想定の 2 倍の同時接続でデータベースのコネクションプールが先に枯渇することが分かり、本番に出す前にプールサイズとコネクション管理を見直せています。本番で起きていたら障害になっていた問題を、ステージングで先に踏めたわけです。

負荷テストの結果は Datadog のダッシュボードと突き合わせ、どのメトリクスが先に天井に当たるかを 1 つずつ確認しました。AI に結果のサマリーと過去の実行結果を比較させると、回帰していないか、改善が本当に効いているかの判定が速くなります。

ダウンタイムを出さずに移行した進め方

稼働中の SaaS を作り替えるうえで、ダウンタイムを出さないことは絶対条件でした。3 ウェーブそれぞれで、次の段取りを守っています。

インフラの変更は Terraform で管理し、本番への適用は必ず計画 (plan) の差分を人間がレビューしてから実行しました。Claude Code に Terraform のコードを書かせると、変更の意図をコメントで添えた状態で出てくるため、レビューがしやすくなります。手で書いた設定とコンソールでの手作業が混在した状態が、スケール期の事故の温床になりがちなので、構成をコードに寄せることそのものが信頼性への投資です。

データベースのインデックス追加は、本番テーブルに対してロックを最小化する形で適用しました。大きなテーブルへの安易なインデックス追加は、適用中に書き込みを止めてしまうことがあります。事前に対象テーブルのサイズと適用方式を確認し、オンラインで追加できる手順を組んでから実行しています。

アプリケーションの切り替えは、新旧を並行稼働させて少しずつトラフィックを寄せるカナリアリリースで行いました。まず全体の 5% を新構成に流し、メトリクスに異常がないことを確認してから 25%、50% と広げ、問題があればすぐ旧構成に戻せる状態を保っています。この進め方なら、仮に想定外の挙動があっても影響を一部のリクエストに閉じ込められます。

結果として、6 週間の作業期間を通じて計画外のダウンタイムはゼロでした。インフラのコード化と段階移行を組み合わせる考え方は、レガシー刷新の事例 10 年もののレガシーシステムを通常見積もり半分でリプレイス とも共通する、FIXIT が止められないシステムを扱うときの基本姿勢です。

成果|レスポンス改善とコストの実数値

3 ウェーブを終えた時点での実数値は次のとおりです。比較対象は、対応前のピーク時計測です。

指標対応前 (ピーク時)対応後 (ピーク時)差分
ダッシュボード初期表示 (p95)6.2 秒0.9 秒-85%
API レスポンス (p95)2,400 ミリ秒380 ミリ秒-84%
ピーク時エラー率約 3.5%0.1% 未満ほぼ解消
耐えられる同時接続数 (負荷テスト)約 800約 4,000約 5 倍
月間インフラコスト基準基準の約 1.3 倍+30%

注目してほしいのは、いちばん下のインフラコストです。スケール対応というと「サーバーを増やしてコストが跳ね上がる」印象を持たれがちですが、今回はコスト増を 3 割程度に抑えました。遅延の大半がコードとクエリの非効率に起因していたため、ハードウェアを大量に積むのではなく、まず非効率を潰したからです。耐えられる同時接続数が約 5 倍になったことを考えれば、1 接続あたりの単価はむしろ大きく下がっています。

クライアントは、この数値を投資家への報告でそのまま使い、信頼性面の懸念を払拭できたと評価しています。レスポンス改善は解約率にも効き、対応後の数か月でピーク時間帯の離脱が目に見えて減りました。スケール設計は地味に見えますが、事業の継続率に直結する投資です。

スケール設計を MVP 段階から仕込むための学び

最後に、この案件から得た再利用可能な学びを 3 つ共有します。

1 つ目は、計測なしにスケール対応を始めないことです。今回いちばんコストパフォーマンスが高かったのは、サーバー増強ではなく N+1 クエリの解消でした。当たりで動いていたら、効果の薄い増強に予算を使っていたはずです。本番に APM を仕込み、1 週間トレースをためてから優先順位を付ける。この一手間が、その後の判断をすべて正しい方向に向けます。

2 つ目は、MVP の段階で「後で効く最小限の仕込み」をしておくことです。MVP でいきなり大規模なマイクロサービス構成を組むのは過剰投資ですが、リクエストにトレース ID を通す、主要なクエリの実行計画をたまに確認する、本番ログを構造化して残す、といった軽い準備があるだけで、スケール期の調査速度がまったく変わります。今回は計測基盤の整備から始める必要があったため、最初の 1 週間がそこに消えました。MVP を作る段階で計測の土台だけでも入れておけば、いざというときの初動が一段速くなります。

3 つ目は、AI 駆動開発はスケール設計と相性が良いということです。スケール対応は、計測データ・クエリの実行計画・コード・インフラ設定という複数の情報を横断しながら判断する作業です。これらを同じ場に並べて読み解き、修正案とテストと負荷シナリオまで一気通貫で出せるのが AI の得意分野でした。人間は、ビジネス影響の重み付けと、本番に出す最終判断という、人間にしかできない部分に集中できます。

MVP が当たった後にアクセス増へどう備えるかは、多くの SaaS が一度は直面する課題です。「重くなってきたが原因が見えない」「止めずに作り替えたい」という段階なら、まず計測から一緒に始めるのが近道です。スケール設計の無料相談は お問い合わせ から、現状のメトリクスや構成のメモを共有いただければ具体的な進め方をご提案します。サービスの全体像は AI 駆動開発 のページもあわせてご覧ください。