メインコンテンツに移動

ストレステストとは?目的・負荷テストとの違い・実施手順・評価指標を企業向けに徹底解説

企業が提供するWebサービスや業務システムでは、「通常の利用状況で正常に動作すること」だけを確認していても、十分な品質保証とはいえません。実際の運用環境では、キャンペーン開始直後、テレビやSNSで商品・サービスが紹介された直後、大型セールの開始時刻、チケット販売や予約受付の開始、月末の締め処理などをきっかけに、短時間で通常の数倍から数十倍にまでアクセスや処理件数が増加することがあります。

このようなリスクを事前に確認するために実施されるのが「ストレステスト」です。ストレステストでは、あえて通常時の想定を超える負荷をシステムへ与え、どの程度まで処理できるのか、どの条件で性能が低下するのか、どのコンポーネントが最初にボトルネックになるのか、そして障害発生後に正常な状態へ復旧できるのかを検証します。

1. ストレステストとは

ストレステストを適切に理解するためには、単に「大量のアクセスを発生させるテスト」と捉えるのではなく、その目的と検証範囲を明確にすることが重要です。

システムの性能を確認するテストには、負荷テスト、ストレステスト、スパイクテスト、耐久テストなど複数の種類があります。それぞれ想定する負荷条件や確認するポイントが異なるため、目的に応じて適切なテスト方法を選択する必要があります。

1.1 ストレステストの基本的な意味

ストレステストとは、システムやアプリケーションに通常運用時の想定を超える負荷を意図的に与え、性能限界や障害発生条件を確認するテストです。例えば、通常は1,000人程度の同時利用を想定しているサービスに対して、2,000人、3,000人、5,000人と段階的に負荷を増加させ、どの地点から性能が低下するかを確認します。

確認するのは、単に「サーバーが停止するかどうか」だけではありません。レスポンスタイムが急激に悪化する地点、エラー率が増加する地点、CPUやメモリ、データベースなどが限界に近づくタイミングも重要な評価対象です。

さらに、限界を超えた際にシステム全体が停止するのか、一部の処理だけが制限されるのか、負荷が下がった後に正常な状態へ戻れるのかといった挙動も確認します。このように、ストレステストはシステムの「最大性能」だけでなく、「限界に近づいたときの状態変化」を把握するためのテストといえます。

1.2 企業システムでストレステストが重要な理由

現代のWebサービスでは、将来のトラフィック量を正確に予測することは困難です。通常時には十分な処理能力を持つシステムでも、テレビやWebメディアでの紹介、SNSでの拡散、大型キャンペーン、セール、予約受付の開始などをきっかけに、短時間で通常の数倍以上のアクセスが集中する可能性があります。

こうしたアクセス増加が本番環境で初めて発生すると、レスポンスの遅延やタイムアウトだけでなく、ログイン不能、購入処理の失敗、予約機能の停止など、事業へ直接影響する障害につながることがあります。ECサイトであれば販売機会の損失につながり、業務システムであれば社内業務そのものが停止する可能性もあります。

そのため企業では、事前にストレステストを実施してシステムの安全な運用範囲を把握し、必要に応じてサーバー増強、オートスケール、アクセス制御、データベース改善などの対策を行うことが重要です。

2. ストレステストと負荷テストの違い

ストレステストを理解するうえで、特に混同されやすいのが「負荷テスト」です。どちらもシステムへ負荷を与えて性能を確認する点では共通していますが、テストで再現する負荷の範囲と、最終的に確認したい内容には違いがあります。

簡単に整理すると、負荷テストは「通常想定される利用条件で問題なく動作するか」を確認するテストであり、ストレステストは「通常の想定を超えた場合にどこまで耐えられるか」を確認するテストです。

2.1 負荷テストは「想定範囲内」の性能を確認する

負荷テストでは、本番環境で想定されるユーザー数やアクセス量を再現し、その状況でシステムが必要な性能を維持できるかを確認します。

例えば、ピーク時に2,000人の同時利用を想定しているWebサービスであれば、2,000人程度のアクセスを発生させ、レスポンスタイム、エラー率、スループット、CPU使用率などが事前に設定した基準を満たしているかを評価します。

つまり負荷テストの中心となる問いは、「通常運用で想定している負荷に対して、システムは問題なくサービスを提供できるか」という点です。リリース前の性能確認や、サーバー構成が要求性能を満たしているかを検証する際に重要になります。

2.2 ストレステストは「想定範囲を超えた状態」を確認する

一方、ストレステストでは通常の想定値を意図的に超える負荷を与えます。2,000人をピークとして想定しているサービスであれば、3,000人、4,000人、5,000人と負荷を増加させ、システムがどの地点まで安定して動作できるかを確認します。

この過程では、レスポンスタイムが悪化し始める地点、スループットが伸びなくなる地点、エラー率が急増する地点などを観測します。また、CPU、メモリ、データベース、外部APIなどのうち、どのコンポーネントが最初に限界へ達するのかも重要な確認項目です。

そのため、負荷テストが「想定条件を満たしていることを確認するテスト」であるのに対して、ストレステストは「想定を超えたときの限界とリスクを明らかにするテスト」と整理できます。

2.3 性能テストには複数の種類がある

性能に関するテストは、ストレステストと負荷テストだけではありません。実際のシステム運用では、急激なアクセス増加や長時間の連続運転など、さまざまな条件を想定する必要があります。

代表的な性能テストを整理すると、以下のようになります。

テスト種類主な目的負荷の特徴主な確認項目
負荷テスト想定条件での性能確認想定範囲内の負荷応答時間、スループット、エラー率
ストレステストシステム限界の把握想定範囲を超えて増加限界値、ボトルネック、障害条件
スパイクテスト急激な負荷増加への耐性確認短時間で急増・急減オートスケール、エラー率、復旧性
耐久テスト長時間稼働時の安定性確認一定負荷を長時間維持メモリリーク、性能劣化、接続状態
キャパシティテスト最大処理能力の把握段階的に負荷を増加最大TPS、最大ユーザー数、必要リソース

例えば、大型セールの開始直後にアクセスが一気に増える状況を確認したい場合には、スパイクテストが適しています。一方、24時間以上サービスを稼働させた際のメモリリークや徐々に発生する性能劣化を確認したい場合には、耐久テストが有効です。

このように、企業システムの性能を総合的に評価するためには、一つのテストだけに依存するのではなく、サービスの特性や想定されるリスクに応じて複数の性能テストを組み合わせることが重要です。3. ストレステストを実施する主な目的

ストレステストは、単にシステムを停止させるために行うものではありません。企業システムでは、通常より高い負荷がかかった際にどこまで安定して稼働できるのかを確認し、性能上の安全圏や潜在的なリスクを把握することが主な目的です。得られた結果は、インフラ増強、アプリケーション改善、監視設定、障害対応などの判断材料として活用できます。

3.1 システムの性能限界を把握する

ストレステストでは、同時ユーザー数やリクエスト数を段階的に増やし、システムがどの程度まで要求を処理できるのかを確認します。重要なのは「サーバーが停止する地点」だけではなく、レスポンスタイムが悪化し始める地点やエラー率が増加する地点まで把握することです。これにより、本番運用でどの程度の負荷まで安定したサービス品質を維持できるのかを判断しやすくなります。

3.2 ボトルネックを特定する

負荷が増加すると、CPUやメモリだけでなく、データベース、外部API、キャッシュ、ネットワークなど、特定の部分が先に限界へ到達する場合があります。ストレステストでは、レスポンスタイムやエラー率と各リソースの状態を合わせて確認することで、性能を制限しているボトルネックを特定します。原因が明確になれば、SQLの最適化やキャッシュ導入、サーバー構成の見直しなど、より具体的な改善策を検討できます。

3.3 障害時の挙動を確認する

システムの処理能力を超えた際に、どのような障害が発生するかを確認することも重要です。一部のリクエストだけがエラーになるのか、システム全体が停止するのか、あるいは重要な機能を維持したまま負荷を制御できるのかを検証します。特に決済や予約などを扱うシステムでは、高負荷時にも二重処理やデータ不整合が発生しないことを確認する必要があります。

3.4 負荷低下後の復旧性を確認する

高負荷状態が終了した後に、システムが正常な状態へ戻れるかもストレステストの重要な確認項目です。負荷が下がってもDB接続やメモリが解放されず、レスポンスの遅延が続く場合には、復旧処理に問題がある可能性があります。そのため、「負荷を増加させる → 限界を確認する → 負荷を下げる → 正常状態への復旧を確認する」という一連の流れで評価することが重要です。

4. ストレステストで確認すべき主要な指標

適切なストレステストでは、「サーバーが停止しなかった」「HTTP 200が返ってきた」という結果だけでは十分ではありません。システムの性能はユーザー体験、アプリケーション、データベース、インフラ、外部サービスなど複数のレイヤーによって決まるため、それぞれのメトリクスを同じ時間軸で確認する必要があります。

特に重要なのは、一つの数値だけを独立して評価しないことです。例えばレスポンスタイムが急増した時点でCPU使用率、DB接続数、キュー長、キャッシュヒット率がどう変化したかを重ね合わせることで、性能劣化の原因をより正確に判断できます。

4.1 レスポンスタイム

レスポンスタイムは、ユーザーがリクエストを送信してから結果を受け取るまでに要する時間であり、Webサービスのユーザー体験を評価する上で最も基本的な指標の一つです。商品一覧表示、ログイン、検索、注文、決済など、処理内容によって許容できるレスポンス時間は異なるため、システム全体の平均だけではなく、APIや機能単位で分けて確認する必要があります。

また、通常負荷では500msだったAPIが、高負荷時に800ms、1.5秒、3秒と徐々に悪化していく過程を確認することで、性能劣化が始まる地点を把握できます。レスポンスタイムが急激に悪化する前に何らかのリソースが飽和している場合、そのメトリクスを本番監視の先行指標として活用することも可能です。

4.2 P95・P99などのパーセンタイル

平均レスポンスタイムだけでは、一部ユーザーに発生している深刻な遅延を把握できない場合があります。そのため、性能テストではP50、P90、P95、P99といったパーセンタイル値を併せて確認することが重要です。

例えば、以下のような結果が得られたとします。

指標レスポンスタイム
平均550ms
P50400ms
P951.8秒
P997.2秒
最大18.5秒

平均値だけを見ると比較的良好に見えますが、P99が7.2秒ということは、100件に1件程度の割合で非常に遅いリクエストが発生していることになります。月間数千万リクエストを扱うサービスであれば、1%でも実際には非常に多くのユーザーが影響を受ける可能性があります。

そのため、企業向けのストレステストでは平均値だけでなく、P95やP99を主要KPIとして設定し、一部ユーザーに偏って発生する「テールレイテンシ」まで評価することが重要です。

4.3 スループット

スループットとは、一定時間内にシステムが実際に処理できるリクエスト数やトランザクション数を示す指標です。Web APIではRPS、業務システムや決済処理ではTPSなどがよく利用されます。

通常は負荷を増加させるにつれてスループットも増加しますが、システムが限界へ近づくと、仮想ユーザー数を増やしてもスループットがほとんど伸びなくなる地点が現れます。さらに負荷を増加させると、タイムアウト、リトライ、ロック競合などが増え、逆にスループットが低下することもあります。

このため、「同時ユーザー数」と「処理件数」は必ずしも比例しません。ストレステストでは、投入した負荷だけでなく実際に成功した処理量を確認し、システムの実効的な処理能力を評価する必要があります。

4.4 エラー率

エラー率は、高負荷状態でサービス品質を判断するための重要な指標です。正常時にはほぼ発生していなかった5xxエラーやタイムアウトが、一定の負荷を超えると急激に増加する場合があります。その地点は、システムのサービス許容限界を判断する重要な材料になります。

確認する代表的なエラーには、HTTP 4xx/5xx、接続タイムアウト、DB接続エラー、外部APIエラー、認証失敗、キュー投入失敗、アプリケーション例外などがあります。

例えば、3,000ユーザーまではエラー率0.2%以下で推移していたものの、3,500ユーザーで3%、4,000ユーザーで15%まで急増した場合、3,000〜3,500ユーザー付近に重要な性能境界が存在していると判断できます。

4.5 CPU・メモリ使用率

CPUとメモリは、ストレステストで最も基本的に確認されるインフラ指標です。ただし、「CPUが高いから悪い」「メモリを多く使っているから問題」と単純に判断するのではなく、レスポンスタイムやスループットとの関係を確認する必要があります。

CPU使用率が80〜90%でも、スループットが十分に伸び、レスポンスも安定しているのであれば、リソースを効率的に利用できていると判断できる場合があります。一方、CPUが30%程度にもかかわらずレスポンスタイムが悪化している場合、CPU以外の場所にボトルネックが存在する可能性があります。

メモリについても、ピーク時の使用量だけではなく、負荷終了後に正常な水準まで戻るかを観測することが重要です。テストを繰り返すたびにメモリ使用量が増え続ける場合には、メモリリークやリソース解放漏れが疑われます。

4.6 データベース関連指標

多くのWebサービスや業務システムでは、アプリケーションサーバーよりも先にデータベースが性能上の制約となるケースがあります。そのため、ストレステストではDBを単なるバックエンドとして扱うのではなく、独立した主要監視対象として詳細に観測する必要があります。

代表的な指標としては、クエリ実行時間、同時接続数、Connection Pool使用率、ロック待ち時間、デッドロック発生数、Buffer Cache Hit Ratio、CPU使用率、メモリ使用量、ディスクI/Oなどがあります。

特に「アプリケーションサーバーを2台から4台へ増やしたにもかかわらずスループットがほとんど伸びない」というケースでは、バックエンドのDBがすでに限界へ到達している可能性があります。その場合、単純な水平スケールだけではなく、SQL改善、インデックス見直し、Read Replica、キャッシュ導入、データ分割など別の対策が必要になります。

4.7 キャッシュ・キュー・外部APIの状態

現在の企業システムでは、アプリケーション単体で処理を完結するケースは少なく、Redisなどのキャッシュ、KafkaやRabbitMQなどのメッセージキュー、決済サービス、認証基盤、外部SaaS APIなど多数のコンポーネントに依存しています。そのため、自社システムのCPUやメモリだけを監視していても、全体のボトルネックを把握できないことがあります。

例えばキャッシュヒット率が高負荷時に急低下すると、普段はキャッシュによって守られているデータベースへ大量のアクセスが集中し、そこから連鎖的な障害につながる可能性があります。また、外部APIがレートリミットを設定している場合、自社のサーバーに余裕があっても外部サービス側で429エラーが増加することがあります。

そのため、キャッシュヒット率、キュー滞留件数、Consumer処理速度、外部APIレスポンスタイム、リトライ回数、Circuit Breakerの状態なども含め、システム全体の依存関係を意識した観測が必要です。

5. ストレステストの実施手順

ストレステストの品質は、実際に負荷を発生させる段階よりも、その前の計画と設計によって大きく左右されます。テスト目的やシナリオを曖昧なまま実行すると、大量のログやグラフは得られても、「結果として何が分かったのか」「どこを改善すればよいのか」を判断できないケースがあります。

そのため、ストレステストは「負荷をかける作業」ではなく、目的定義、KPI設計、シナリオ作成、テスト実行、監視、分析、改善、再テストまでを含めた一連のプロセスとして考える必要があります。

5.1 テスト目的を定義する

最初に、「今回のストレステストで何を明らかにしたいのか」を具体的に定義します。例えば、「最大5,000同時ユーザーでも注文機能を維持できるか」「API Gatewayが何RPSまで処理できるか」「突発的なアクセス増加時にオートスケールが間に合うか」「DBがどの程度のTPSでボトルネックになるか」などです。

目的を明確にすると、必要なシナリオや指標も自然に決まります。逆に目的が「とりあえず高負荷をかけてみる」といった曖昧な状態では、テスト終了後に得られた数値の意味を判断しにくくなります。

5.2 KPIと合格基準を決める

次に、テスト結果を評価するためのKPIと許容基準を事前に定義します。数値基準がない場合、「多少遅かったが問題ない」「CPUが高かったが落ちなかったので成功」といった主観的な評価になりやすいためです。

例えば、以下のような基準を設定できます。

  • P95レスポンスタイム:2秒以内
  • P99レスポンスタイム:5秒以内
  • エラー率:1%未満
  • 決済成功率:99.9%以上
  • DB Connection Pool使用率:継続的に90%未満
  • データ不整合:0件
  • 負荷終了後10分以内に通常性能へ復旧

このように性能だけでなく、エラー、整合性、復旧時間まで含めて基準を設定すると、より実運用に近い評価が可能になります。

5.3 本番環境に近いユーザーシナリオを設計する

実際のユーザーは、同じAPIだけを連続して呼び続けるわけではありません。ECサイトであれば、トップページ閲覧、商品検索、商品詳細、カート追加、ログイン、注文、決済など複数の操作を行います。そのため、テストでは実際のユーザー行動に近いシナリオを設計する必要があります。

可能であれば、本番アクセスログや分析データを利用し、「商品閲覧60%、検索20%、カート追加10%、購入5%、その他5%」といった実際の処理比率を再現します。また、ページを閲覧する時間や入力操作を想定したThink Timeも設定することで、より現実的な負荷モデルになります。

5.4 テストデータを準備する

テストシナリオだけ本番に近づけても、データ量が大きく異なれば性能結果は現実と乖離します。例えば本番では商品データ500万件、注文履歴1億件が存在するのに、テスト環境には数百件しかない場合、検索、JOIN、集計、インデックス利用状況などを正しく評価できません。

そのため、可能な限り本番に近いデータ量とデータ分布を準備します。単純な件数だけでなく、人気商品へのアクセス集中、特定ユーザーへの履歴集中、古いデータと新しいデータの比率など、実際のデータ偏りも性能へ影響する可能性があります。

5.5 段階的に負荷を増加させる

ストレステストでは、最初から最大負荷を与えるよりも、一定時間ごとに段階的に負荷を増やす方法が分析しやすくなります。

例えば、

500 → 1,000 → 2,000 → 3,000 → 4,000 → 5,000ユーザー

というように増加させ、それぞれの段階で5〜15分程度状態を維持します。各段階のレスポンスタイム、スループット、エラー率、リソース使用量を比較することで、性能が直線的に悪化しているのか、それとも特定地点から急激に悪化しているのかを把握できます。

5.6 システム限界を観測する

負荷増加中は、「いつ障害が発生したか」だけではなく、「障害に至るまでどの指標がどの順番で変化したか」を確認します。例えばDB Connection Poolが先に90%を超え、その数分後にP95が上昇し、さらに負荷を増やしたところ5xxエラーが発生したという流れを確認できれば、DB接続数が先行指標となっている可能性があります。

このような時間的な前後関係を把握することで、本番では障害になる前にアラートを出したり、オートスケールやアクセス制御を開始したりできるようになります。

5.7 負荷を下げて復旧状態を確認する

限界まで負荷をかけた後は、通常水準まで負荷を下げ、その後のシステム状態を一定時間監視します。CPU、メモリ、DB接続数、P95、エラー率、キュー長などが正常な値へ戻るかを確認します。

特に重要なのは、負荷がなくなったにもかかわらず遅延が残るケースです。キューが大量に滞留している、リトライ処理が集中している、キャッシュ再構築が進んでいるなど、ピーク終了後にもサービス品質へ影響する問題が存在する可能性があります。

5.8 結果を分析して改善する

テスト終了後は、グラフを貼っただけのレポートではなく、「何が発生したか」「なぜ発生した可能性があるか」「どの改善策が必要か」という流れで整理します。

発見事項原因候補改善案
3,500ユーザーからP95が急上昇DB Connection Pool枯渇Pool調整、SQL最適化
API CPU使用率が95%へ到達シリアライズ処理が高負荷処理最適化、水平スケール
Queueが5万件まで滞留Consumer処理能力不足Consumer増強
外部APIのTimeoutが増加Rate Limit・外部遅延Circuit Breaker、Cache導入

このように問題と改善策を対応付けることで、ストレステストを具体的な開発タスクへ落とし込みやすくなります。

5.9 同一条件で再テストする

改善を実施した後は、できるだけ同じ負荷モデル、テストデータ、実行時間、システム条件で再テストします。毎回条件が変わってしまうと、性能改善が本当に施策によるものなのか、それともテスト条件の違いによるものなのか判断できません。

Before/AfterでP95、P99、最大TPS、エラー率、CPU使用率などを比較することで、改善効果を定量化できます。性能改善では一つのボトルネックを解消すると次のボトルネックが表面化することも多いため、この再テストを継続的に繰り返すことが重要です。

6. ストレステストを成功させるためのポイント

ストレステストを成功させるためには、単に大量のリクエストを送信できればよいわけではありません。企業の意思決定に利用できるテストにするためには、結果の再現性、実環境との近似性、分析可能性を確保する必要があります。

6.1 本番環境に近い条件を準備する

可能な限り、CPU、メモリ、ネットワーク、DB構成、データ量、キャッシュ、外部依存サービスなどを本番環境へ近づけます。特にDBデータ量や外部API構成が大きく異なる場合、テスト環境では問題がなくても本番で性能問題が発生する可能性があります。

完全に同じ環境を準備できない場合には、差分を明文化することが重要です。「テスト環境は本番CPUの50%」「DBデータ量は本番の30%」「外部APIはMockを使用」などの条件を記録しておけば、結果を解釈する際にどの程度補正が必要か判断しやすくなります。

6.2 最大ユーザー数だけを評価しない

「最大10,000ユーザーまで接続できた」という数字は分かりやすい一方で、その数字だけではシステム品質を評価できません。例えば8,000ユーザー時点でP95が8秒、エラー率が5%になっていれば、10,000ユーザーまで「動作した」としても、サービス品質としては成立していない可能性があります。

そのため、最大同時ユーザー数だけでなく、性能劣化開始点、SLO超過地点、エラー急増地点、スループット飽和地点などを併せて評価することが重要です。

6.3 実際のユーザー行動を再現する

テストでは、リクエスト完了直後に次の操作を実行するようなシナリオを作ると、実際のユーザーよりもはるかに高頻度でAPIが呼び出される場合があります。一方、同じページだけを繰り返し取得するとキャッシュが効きすぎ、実運用よりも軽い負荷になることもあります。

可能であればアクセスログを分析し、利用機能の割合、Think Time、セッション継続時間、ユーザーごとの操作パターンなどをモデル化することで、より現実的なストレステストになります。

6.4 負荷生成側の性能も監視する

見落とされやすいポイントとして、負荷生成ツール側の性能があります。JMeterやk6などを実行するGeneratorがCPU100%、メモリ不足、ネットワーク帯域飽和になっている場合、それ以上の負荷を生成できません。

この状態でRPSが伸びなくなった場合、「対象システムの限界」と誤認する可能性があります。そのため、大規模テストでは複数Generatorへ分散し、負荷生成環境自体のCPU、メモリ、Network、エラー率も監視する必要があります。

6.5 ボトルネックを一つずつ改善する

性能問題が見つかった際に、サーバー台数、DB Pool、インデックス、キャッシュ、アプリケーションコードなどを同時に変更すると、何が改善へ寄与したのか分からなくなります。

可能な限り一つずつ改善し、同一条件で再テストすることで、それぞれの施策の効果を数値で確認できます。このプロセスを繰り返すことによって、システムの限界を段階的に引き上げることができます。

7. ストレステストでよくある失敗

ストレステストでは、対象システムの問題だけでなく、テスト方法そのものが不適切なために誤った結果が得られるケースもあります。特に大規模システムでは、負荷生成環境、キャッシュ、データ量、本番との差異など、テスト結果へ影響する要因が非常に多いため注意が必要です。

7.1 負荷生成サーバーが先に限界になる

最も典型的な失敗の一つが、対象システムではなく負荷生成側が先に限界へ到達するケースです。仮想ユーザー数を10,000へ増加させても、GeneratorのCPUが100%になっていれば、実際に発行されるRPSは途中から増えなくなる可能性があります。

その状態を対象システムの最大性能と誤認すると、テスト結果全体の信頼性が失われます。そのためGenerator側のメトリクスも監視し、必要に応じて複数台へ分散します。

7.2 キャッシュの影響を考慮していない

キャッシュはシステム性能へ非常に大きな影響を与えます。同じ商品や同じAPIだけを繰り返しアクセスすると、キャッシュヒット率がほぼ100%となり、DBへの負荷が極端に少なくなる可能性があります。

一方、すべてのリクエストで異なるランダムデータを要求すると、実際のサービスよりもキャッシュミス率が高くなり、必要以上に重い条件になることがあります。

そのため、本番環境のアクセスパターンやキャッシュヒット率を参考にしながら、実際に近いデータアクセス分布を再現することが重要です。

7.3 非現実的なユーザー操作を再現している

現実のユーザーは画面を読んだり、入力したり、商品を比較したりするため、操作と操作の間に一定の時間があります。テストではこのThink Timeを無視して高速にAPIを連続実行すると、本番では起こりにくい極端な負荷を生成することがあります。

絶対的なシステム限界を確認する目的であれば有効な場合もありますが、本番トラフィックを再現するテストとしては現実性が低くなるため、目的に応じてシナリオを分ける必要があります。

7.4 平均レスポンスタイムだけで判断する

平均値は、多数の正常なリクエストによって少数の極端な遅延が隠れてしまうという問題があります。特にユーザー数が多いサービスでは、全体の1%だけに発生する問題でも、実際には数万人が影響を受ける可能性があります。

そのためP95、P99、最大値、エラー率などを併用し、性能分布全体を確認することが重要です。

7.5 テスト環境と本番環境の差を無視する

テスト環境と本番環境でCPU、メモリ、DB構成、データ量、ネットワーク、キャッシュ構成などが異なる場合、テスト結果をそのまま本番へ適用することはできません。

「テスト環境で5,000ユーザーまで問題なかったから、本番も同じ」と考えるのではなく、環境差を明文化し、その差が性能へどの程度影響するかを考慮する必要があります。

7.6 限界に到達した時点でテストを終了する

エラーが発生した瞬間にテストを終了すると、システムがその後正常に復旧できるか確認できません。本番では負荷ピーク終了後もサービスを継続する必要があるため、回復性は非常に重要です。

負荷を下げた後にレスポンスタイム、DB接続数、キュー長、メモリなどが正常値へ戻るまで観測し、必要であれば復旧時間もKPIとして記録します。

8. ストレステスト結果をシステム改善につなげる方法

ストレステストは、結果レポートを作成すること自体がゴールではありません。本当の価値は、得られたデータをアプリケーション設計、インフラ、監視、障害対応、事業計画などへ具体的に反映することにあります。

8.1 キャパシティプランニングに活用する

ストレステストによって現在の安全な処理能力が分かれば、将来いつリソース増強が必要になるか予測できます。例えば現在のピークが1,500TPS、安全圏が2,000TPSであり、トラフィックが年間30%程度増加しているのであれば、現在の余裕がいつ失われるかを推定できます。

このように性能データを事業成長予測と組み合わせることで、「障害が起きてから増強する」のではなく、事前に予算、インフラ、開発スケジュールを計画できます。

8.2 オートスケール設計を改善する

ストレステストでは、どの指標が性能劣化より先に変化するかを確認できます。例えばCPU使用率はそれほど高くないのに、Queue Depthが先に増加するシステムであれば、CPUよりもQueue Lengthをオートスケール条件へ利用した方が適切な場合があります。

また、スケールアウトには新規インスタンス起動やWarm-upなど一定の時間が必要です。そのため障害直前にスケールを開始しても間に合わない可能性があり、ストレステストを通じて「何%の負荷でスケール開始するか」「何台追加すれば性能が回復するか」を検証することが重要です。

8.3 データベースを最適化する

DBがボトルネックであることが判明した場合には、インデックス、SQL、Connection Pool、Read Replica、パーティショニング、キャッシュなど複数の改善方法を検討します。

ただし、DBスペックだけを上げればよいとは限りません。例えば不要なFull Scanが発生しているSQLであれば、より高性能なDBへ変更しても根本的な問題は残ります。そのため、実行計画やSlow Query Logを確認しながら原因を特定することが重要です。

8.4 キャッシュ戦略を改善する

アクセス集中時には、同じ商品情報や設定情報などが何度も取得されることがあります。適切なキャッシュを導入すれば、DBや外部APIへのアクセス数を大幅に減らせる可能性があります。

一方でTTLが短すぎる場合や、大量のキャッシュが同時に期限切れになる場合にはCache Stampedeが発生し、逆にバックエンドへ急激な負荷がかかることがあります。そのため、ストレステストではキャッシュの有無だけでなく、期限切れや再構築時の挙動まで確認すると効果的です。

8.5 監視・アラート閾値を改善する

ストレステストから「障害が発生する前の兆候」を把握できれば、本番監視の精度を高められます。例えばDB Pool使用率85%を超えた付近からP95が急激に悪化することが分かった場合、80%程度をWarning、90%をCriticalとして設定するなど、実測に基づいたアラート設計ができます。

これによって、「サービスが停止してから通知される監視」ではなく、「障害へ近づいている段階で対応できる監視」へ改善できます。

8.6 障害対応計画へ反映する

ストレステストによってシステムの限界条件が明確になれば、障害対応Runbookも具体化できます。

例えば、

  1. 同時アクセス5,000以上で性能劣化開始
  2. DB Connection Pool 80%で警戒
  3. 90%超過で非重要機能を制限
  4. P95が5秒を超えた場合はWaiting Roomを有効化
  5. Queueが一定件数を超えた場合はConsumerを増強

といったように、技術的な性能データを実際の運用アクションへ変換できます。

9. ストレステストを実施すべきタイミング

ストレステストは、サービス公開前に一度実施すれば終わりというものではありません。ユーザー数、データ量、コード、インフラ、外部APIなどは継続的に変化するため、システムの性能特性も時間とともに変わります。

9.1 新規サービスのリリース前

新規サービスでは、実際のアクセス数や利用パターンを完全に予測することが難しいため、正式公開前にストレステストを行い、最低限の安全圏を把握しておくことが重要です。

特にマーケティング施策と同時に公開するサービスでは、公開直後から想定以上のアクセスが発生する可能性があります。

9.2 大型キャンペーンやセールの前

大型セール、テレビCM、SNSキャンペーン、チケット販売、予約受付など、開始時刻が明確なイベントでは短時間にアクセスが集中しやすくなります。

この場合、1日平均や1時間平均のトラフィックではなく、数秒・数分単位のピークトラフィックを想定する必要があります。

9.3 アーキテクチャ変更後

クラウド移行、データベース変更、マイクロサービス化、キャッシュ導入、API Gateway変更、認証基盤刷新など、大規模なシステム変更後には性能特性が以前と変わる可能性があります。

機能テストで正常に動作していても、以前と同等以上の性能を維持できているとは限らないため、性能テストを再実施する必要があります。

9.4 データ量が大幅に増加したとき

コードに変更がなくても、データ量が増えれば性能は変化します。特に検索、JOIN、集計、ランキング生成、バッチ処理などはデータ件数の影響を受けやすく、初期には問題なかった処理が数年後にボトルネックになることがあります。

そのため、データ量が当初想定の2倍、5倍、10倍へ増加した場合には、現在のキャパシティを再評価することが重要です。

9.5 利用ユーザー数が大きく増加したとき

サービスが成長し、通常ピークが以前ストレステストで確認した安全圏へ近づいてきた場合には、再度テストを実施する必要があります。

「以前のテストでは問題なかった」という結果は、現在のコード、現在のデータ量、現在のインフラを保証するものではありません。現在の条件で安全マージンがどの程度残っているかを再評価することが重要です。

9.6 定期的な性能評価として実施する

重要なサービスでは、四半期、半年、主要リリースごとなど、一定周期で性能評価を行うことも効果的です。

継続的な機能追加によって1回ごとの性能低下は小さくても、複数回積み重なることで大きな性能リグレッションになる場合があります。定期テストを実施することで、こうした劣化を早期に発見できます。

10. ストレステストで重要なのは「最大値」ではなく「安全圏」

ストレステストの結果では、「最大10,000同時ユーザー」「最大3,000TPS」といった数字が注目されやすい傾向があります。しかし、企業の実運用で重要なのは、理論上の最大値ではなく、安定したユーザー体験と十分な障害耐性を維持できる安全な運用範囲です。

10.1 性能劣化開始点を特定する

システムは最大処理能力へ到達した瞬間に突然停止するとは限りません。多くの場合、限界へ近づくにつれてレスポンスタイム、キュー長、ロック待ち、エラー率などが徐々に悪化します。

例えば最大5,000ユーザーまで処理できたとしても、3,500ユーザーからP95が1秒から4秒へ急上昇するのであれば、実務上は3,500ユーザー付近が重要な性能劣化開始点です。この地点を把握できれば、限界になる前にオートスケール、Rate Limiting、Waiting Roomなどを作動させることができます。

10.2 許容限界と障害発生点を分けて考える

「システムが稼働していること」と「サービス品質を維持できていること」は別です。

状態同時ユーザーP95エラー率評価
通常域2,0000.8秒0.1%安定
劣化開始3,0001.8秒0.3%注意
許容限界4,0003.0秒1.0%上限
障害域5,0008.5秒12%運用不可

この場合、システムが最大5,000ユーザーまで動作していても、「5,000ユーザー対応システム」と判断するのは適切ではありません。実際の運用上限は4,000未満として考える方が安全です。

10.3 安全マージンを設定する

本番環境では、テスト時には存在しなかったさまざまな要因が重なります。外部APIの一時的遅延、バックアップ処理、突発的な重いクエリ、Botアクセス、ネットワーク遅延などです。

そのため、ストレステストで確認した安全限界を100%使い切るのではなく、一定の安全マージンを持たせます。例えば許容限界が4,000ユーザーであれば、通常運用では2,500〜3,000程度を目安とし、それ以上では事前にスケールアウトを開始する設計が考えられます。

10.4 「安全に失敗する」システムを設計する

どのシステムにも処理能力の限界があるため、限界を完全になくすことはできません。そのため重要なのは、限界を超えた際にどのように安全に失敗するかです。

Rate Limiting、Waiting Room、Circuit Breaker、タイムアウト、機能優先順位制御、Graceful Degradationなどを組み合わせることで、サービス全体の停止を避けられる場合があります。

例えばECサイトでは、高負荷時にレコメンド機能やランキング表示を一時停止しても、商品検索、カート、決済を維持できれば事業への影響を抑えられます。このようにすべてを守るのではなく、重要度に応じて機能を段階的に縮退させる設計も、ストレステストで確認すべき重要なポイントです。

11. ストレステストを継続的な品質改善へ組み込む

システム性能は、一度ストレステストを実施して合格すれば、その後も同じ状態が維持されるわけではありません。日々のコード変更、ライブラリ更新、データ増加、ユーザー増加、クラウド構成変更、外部サービス仕様変更などによって、性能特性は継続的に変化します。

そのため、成熟した開発・運用体制では、ストレステストや性能テストをリリース前だけの特別なイベントではなく、継続的な品質管理プロセスとして組み込むことが重要です。

11.1 CI/CDと性能テストを連携する

すべてのPull Requestで数千ユーザー規模の大規模ストレステストを実行することは、コストや時間の面から現実的ではありません。しかし、主要APIへ一定量のリクエストを送る軽量なPerformance TestをCI/CDへ組み込むことは可能です。

例えばP95が前回より20%以上悪化した場合や、同一負荷でCPU使用率が一定割合以上増えた場合に警告を出すことで、性能リグレッションを開発段階で検出できます。

大規模なストレステストは、Release Candidate、月次、四半期、大型施策前などに分けて実施すると、コストと品質のバランスを取りやすくなります。

11.2 過去のテスト結果と比較する

性能テストは単独の結果だけを見るよりも、過去データと継続的に比較することで価値が高まります。

例えば、

  • 最大安全TPS
  • P95/P99レスポンスタイム
  • エラー発生開始点
  • CPU・メモリ使用量
  • DBクエリ時間
  • Queue滞留量
  • 正常状態への復旧時間

などをテストごとに記録しておけば、現在のシステムが以前より改善しているのか、それとも少しずつ劣化しているのかを把握できます。

11.3 性能劣化をリグレッションとして管理する

機能的には正しいコードでも、以前100msだった処理が200msになれば、トラフィックの多いサービスでは大きな問題になる可能性があります。一つのAPIではわずかな差でも、1日数千万回実行されればCPUやインフラコストへ大きな影響を与えます。

そのため、性能劣化も機能バグと同様にPerformance Regressionとして管理し、Issue化、原因分析、改善、再テストまで行うことが重要です。

11.4 開発・運用・事業部門で結果を共有する

ストレステストの結果は、QA、SRE、インフラチームだけが理解していれば十分というものではありません。特にマーケティング部門が大型キャンペーンを計画している場合、現在のシステムが安全に処理できるユーザー数や、予想トラフィックに対してどの程度余裕があるのかは、事業計画にも直接影響します。

ただし、事業部門へCPU使用率、GC Pause、DB Buffer Hit Ratioなどの技術指標をそのまま共有しても理解しにくいため、以下のような形へ変換すると効果的です。

  • 現在の安全な処理能力
  • 今回施策で予測されるピークトラフィック
  • 現在残っている安全マージン
  • 想定を超えた場合の主要リスク
  • 必要な追加対策
  • 対策を実施しない場合の事業影響

このようにストレステストを技術部門だけの検証作業として終わらせず、開発、運用、マーケティング、事業企画などを横断した意思決定材料として活用することで、システム品質だけでなく、企業全体のサービス運営リスクを低減できます。

12. 企業がストレステストを実施する際のチェックリスト

最後に、実務でストレステストを計画する際に確認しておきたいポイントを整理します。

12.1 テスト前に確認する項目

  • テストの目的が明確になっているか
  • 想定ピークアクセス数を把握しているか
  • KPIと許容値を定義しているか
  • 本番に近いシナリオを準備しているか
  • テストデータ量が十分か
  • 負荷生成環境の性能が十分か
  • システム監視を準備しているか
  • テスト終了条件を設定しているか

12.2 テスト後に確認する項目

  • 性能劣化開始点を把握できたか
  • 最大処理能力を確認できたか
  • ボトルネックを特定できたか
  • エラー発生条件を把握できたか
  • 復旧性を確認できたか
  • 改善施策を明確にできたか
  • 再テスト条件を保存できたか

おわりに

ストレステストとは、システムに通常想定を超える負荷を意図的に与え、性能限界、ボトルネック、障害時の挙動、そして負荷低下後の復旧性を確認する性能テストです。負荷テストが主に「想定された利用範囲で要求性能を満たしているか」を検証するのに対し、ストレステストではその想定範囲を超えることで、システムがどの地点から劣化し、どの条件でサービス品質を維持できなくなるのかを明らかにします。

また、企業にとって重要なのは「最大何人まで接続できるか」という単一の数字ではありません。通常運用域、性能劣化開始点、許容限界、障害発生点、復旧状態を一連の性能特性として把握し、そこから安全な運用範囲を設定することが重要です。レスポンスタイム、P95・P99、スループット、エラー率、CPU、メモリ、データベース接続数、キャッシュ、外部APIなどを総合的に分析することで、システムの実際の弱点が見えやすくなります。

さらに、ストレステストで発見した問題は、アプリケーションの最適化だけでなく、キャパシティプランニング、オートスケール、監視アラート、障害対応、キャンペーン設計などにも活用できます。つまり、ストレステストは単なるQA工程ではなく、開発・運用・事業を横断してサービスの安定性を高めるための重要な取り組みです。

システムの利用規模やデータ量は時間とともに変化します。そのため、ストレステストをリリース前の一度きりの作業として扱うのではなく、重要なシステム変更や事業成長に合わせて継続的に実施し、現在のシステムがどこまで安全に運用できるのかを定期的に確認することが、長期的なサービス品質の維持につながります。

LINE Chat