目次
「このサービス、サーバーはどのくらいのスペックが必要ですか?」「月額いくらかかりますか?」と聞かれて、根拠のある数字を答えられずに困った経験はないでしょうか。とりあえず大きめのインスタンスを選んで毎月ムダな費用を払い続けたり、逆に小さすぎてキャンペーン当日に落ちたりするのは、見積もりの手順を持っていないことが原因です。
この記事では、月間PVのような事業側の数字から、ピーク時の秒間リクエスト数、1リクエストあたりのリソース消費、必要なサーバー台数、そして月額費用までを一本の計算でつなぐ方法を解説します。負荷テストの実施方法そのものは負荷テストのやり方とツール選びで扱っているので、ここでは「テスト結果をどう読み、どう見積もりに使うか」に集中します。読み終えれば、自分で見積もりシートを作り、根拠を説明できるようになります。
キャパシティプランニングの基本|月間PVをピーク秒間リクエストに換算する
平均ではなくピークで設計する
キャパシティプランニングとは、想定される負荷に対して必要なリソース(CPU・メモリ・ネットワーク・DB)を見積もり、余裕を持って確保する活動です。最初の落とし穴は「平均で計算してしまう」ことです。月間100万PVを単純に秒で割ると約0.39リクエスト/秒ですが、アクセスは昼休みや夜、キャンペーン告知直後に集中します。サーバーは平均ではなくピークに耐えなければなりません。
換算は次の手順で行います。
- 月間PVを日次に直す(÷30)。
- 1日のうち「ピーク1時間」に何%が集中するかを決める。アクセス解析があれば実測値、なければ業務系で15〜20%、一般消費者向けで10%前後と仮置きすることが多いです。
- ピーク1時間のPVを3,600で割り、ピーク秒間リクエスト数(RPS)を出す。
- 1PVあたりのAPI・静的ファイル・画像などのリクエスト数を掛ける(サーバーに届く実リクエスト数にする)。
- キャンペーンやテレビ露出などのスパイク係数を掛ける。
# 月間100万PV、ピーク1時間に15%集中、1PVあたり動的リクエスト3、スパイク係数3の例
monthly_pv = 1_000_000
daily_pv = monthly_pv / 30 # 約33,333 PV/日
peak_hour_pv = daily_pv * 0.15 # 約5,000 PV/時
peak_rps = peak_hour_pv / 3600 # 約1.4 PV/秒
dynamic_rps = peak_rps * 3 # 約4.2 リクエスト/秒
design_rps = dynamic_rps * 3 # スパイク込みで約12.5 リクエスト/秒
「月間100万PV」と聞くと大規模に感じますが、設計上のピークは秒間十数リクエストです。この数字を出すだけで、多くの中小規模サービスが「小さなインスタンス1〜2台で十分」と分かります。
静的コンテンツはCDNに逃がして計算から外す
画像やCSS、JavaScriptをCDNから配信していれば、それらはサーバーの計算に含めなくて構いません。逆に、CDNを使っていない場合は1PVあたりのリクエスト数が数十になり、帯域とワーカーを大きく消費します。見積もりの前に「何をサーバーが処理し、何をCDNに任せるか」を切り分けておくと、数字が現実に近づきます。
1リクエストあたりのCPU・メモリ・DBクエリから逆算する
「1リクエストのコスト」を実測する
必要台数は「秒間リクエスト数 × 1リクエストあたりの処理時間 ÷ 並列で処理できる数」で決まります。そのためには1リクエストのコストを知る必要があり、これは推測ではなく実測します。ステージング環境で単一のサーバーに負荷をかけ、次の3つを記録してください。
- CPU時間:1リクエストの処理にCPUを何ミリ秒使うか。負荷テスト中のCPU使用率とRPSから逆算できます(CPU使用率80%でRPS 100なら、1コアあたり約8ms/リクエスト)。
- メモリ:ワーカープロセス1つあたりの常駐メモリ。Rails・Django・PHP-FPMなどはワーカー数×常駐メモリがそのまま必要量になります。
- DBクエリ数と時間:1リクエストが発行するクエリ数と合計時間。DBは横に増やしにくいので、ここがボトルネックになりやすい部分です。
# 負荷テスト中に別端末で観測する例(Linux)
# CPU・メモリの推移を1秒ごとに記録
vmstat 1 | tee vmstat.log
# ワーカープロセスの常駐メモリ(RSS)を確認
ps -o pid,rss,cmd -C gunicorn | sort -k2 -n
# PostgreSQL:接続数とアクティブクエリ数
psql -c "SELECT state, count(*) FROM pg_stat_activity GROUP BY state;"
必要ワーカー数と台数を計算する
1リクエストの平均処理時間が50ms、設計RPSが12.5なら、同時に処理中のリクエストは平均で12.5×0.05=約0.6件です。これだけ見れば1ワーカーでも足りそうですが、実際には外部API待ちやDB待ちで処理時間が伸びる瞬間があり、待ち行列ができます。実務では次の式で概算し、余裕率を掛けます。
必要ワーカー数 = 設計RPS × 平均処理時間(秒) × 余裕率
= 12.5 × 0.05 × 3 ≒ 2 → 実際には最低4〜6ワーカーを確保
必要メモリ = ワーカー数 × ワーカーあたりRSS + OS・ミドルウェア分
= 6 × 150MB + 500MB ≒ 1.4GB → 2GB以上のインスタンス
必要CPU = 設計RPS × CPU時間(秒) × 余裕率
= 12.5 × 0.008 × 3 ≒ 0.3コア → 2vCPUで十分
ワーカー数とスレッドモデルの考え方は同時接続数とワーカー数の見積もりで詳しく説明しています。DB側の接続数もワーカー数に比例して増えるため、コネクションプーリングで上限を抑える設計とセットで考えてください。
余裕率とスパイクをどう見込むか
使用率の目標を決める
CPU使用率100%を前提に設計してはいけません。使用率が高くなるほど待ち行列が指数的に伸び、レスポンスが急激に悪化するからです。目安として、定常時のピークでCPU使用率50〜60%、スパイク時でも80%を超えない設計にすることが多く、これが「余裕率2〜3倍」の根拠です。
| 状況 | 推奨する余裕率 | 理由 |
|---|---|---|
| 社内向け業務システム(利用者数が固定) | 1.5〜2倍 | ピークが予測しやすい |
| 一般向けWebサービス(告知・SNSあり) | 3倍前後 | 予期しない流入がある |
| キャンペーン・テレビ露出が予定されている | 5〜10倍、または一時的なスケールアウト | 短時間に桁違いの流入 |
| オートスケール前提 | 定常は2倍、増加分はスケールで吸収 | ウォームアップ時間分の余裕が必要 |
オートスケールを使う場合も「ゼロから間に合う」わけではなく、新しいインスタンスが起動して受け付け可能になるまでの数分間は既存のサーバーで耐える必要があります。その設計はオートスケーリングの仕組みと設計を参照してください。
スパイクは「秒間」で見る
プッシュ通知やメルマガ配信は、送信直後の数十秒に流入が集中します。1時間単位の集計では見えないため、過去の配信時のアクセスログを秒単位で集計して実測しておくと、根拠のあるスパイク係数が得られます。
# Nginxアクセスログから秒ごとのリクエスト数を集計し、上位を表示
awk '{print $4}' /var/log/nginx/access.log | cut -d: -f2-4 | sort | uniq -c | sort -rn | head
負荷テスト結果の読み方|p95・p99が意味すること
平均レスポンスタイムは当てにならない
負荷テストの結果で最初に見るべきは平均ではなくパーセンタイルです。p95とは「全リクエストのうち95%はこの時間以内に返った」という値で、p99は99%です。平均が100msでもp99が3秒なら、100人に1人は3秒待たされており、その1人がカートに商品を入れた瞬間の利用者かもしれません。
実務での見方は次のとおりです。
- p50(中央値):典型的な体感速度。ここが遅ければアプリ自体の改善が必要。
- p95:SLOの基準に使うことが多い値。「p95が500ms以内」のように目標を立てる。
- p99:GC停止、DBロック待ち、コネクション枯渇などの「たまに起こる異常」が現れる。RPSを上げていってp99が急に跳ねた地点が、そのサーバーの実質的な限界。
- エラー率:タイムアウトや5xxが出始めたRPSは、限界を越えた証拠。
RPSを段階的に上げていき、「p99が跳ね上がるかエラーが出始める直前のRPS」を「1台あたりの処理能力」として記録します。この値を設計RPSで割れば、必要台数が出ます。
トラブル事例:負荷テストは通ったのに本番で落ちた
症状:ステージングでRPS 200まで問題なく処理できたので本番も同じ構成にしたが、リリース初日の告知直後、RPS 60程度でレスポンスが10秒を超え、5xxが多発した。
原因:負荷テストのシナリオがトップページのGETだけだった。本番ではログイン後のマイページが多く呼ばれ、1リクエストで十数回のDBクエリと外部決済APIへの問い合わせが発生していた。またステージングのDBはデータ件数が本番の100分の1で、インデックスが効かないクエリでも高速に返っていた。
対処:暫定的にインスタンスを2台増やし、外部APIの呼び出しにタイムアウトを設定。恒久対策として、本番相当のデータ量を投入したステージングで、実際のアクセス比率(トップ6割・マイページ3割・購入1割など)を再現したシナリオで再テストし、1リクエストあたりのクエリ数の上限をコードレビューの基準に加えた。
見積もりシートの作り方と「小さく始めて計測で増やす」運用
見積もりシートの構成
見積もりは頭の中ではなく、誰でも再計算できるシートにします。列は次の3ブロックに分けると説明しやすくなります。
| ブロック | 項目 | 入力元 |
|---|---|---|
| 前提(事業側) | 月間PV、ピーク集中率、1PVあたりリクエスト数、スパイク係数 | アクセス解析・事業計画・仮置き |
| 実測(技術側) | CPU時間/リクエスト、RSS/ワーカー、クエリ数/リクエスト、1台あたり限界RPS | 負荷テスト結果 |
| 算出 | 設計RPS、必要ワーカー数、必要vCPU・メモリ、台数、月額費用 | 上記からの計算式 |
費用の列には、インスタンス代だけでなくDB、ストレージ、データ転送、バックアップ、監視を含めてください。特にデータ転送量は「1PVあたりの平均転送KB × 月間PV」で概算でき、見落とすと請求で驚くことになります。仮置きした値には必ず「仮」と印をつけ、本番稼働後に実測値へ置き換える運用にします。
最初から正解を当てようとしない
クラウドの利点は、見積もりが外れても後から直せることです。したがって現実的な進め方は次のようになります。
- 上記の計算で出た最小構成+余裕率で開始する。
- CPU使用率、メモリ、p95レスポンス、DB接続数を監視し、閾値(CPU 60%など)でアラートを出す。
- 2〜4週間の実測値をシートの「仮」欄に反映し、再計算する。
- 閾値に近づいたら、まずアプリ・クエリ改善で1リクエストのコストを下げ、それでも足りなければスケールアップ/アウトする。
- 逆に使用率が常に20%以下なら、一段階小さいインスタンスに落として費用を下げる。
スケールの判断を「なんとなく重い気がする」ではなく、シートの数値で行うことが目的です。既に稼働中のサービスでムダを見つける具体的な方法はクラウドコスト削減の方法にまとめています。
まとめ
キャパシティプランニングは、月間PVをピーク秒間リクエストに換算し、負荷テストで実測した1リクエストあたりのCPU・メモリ・DB負荷を掛け合わせ、余裕率を乗せて台数と費用に落とし込む作業です。平均ではなくピークとp95/p99で判断すること、静的コンテンツをCDNに逃がしてから計算すること、そして見積もりを再計算可能なシートにして実測で更新し続けることが要点です。
まずは自社サービスの月間PVとピーク集中率を入力し、ステージングで1リクエストのコストを一度測ってみてください。それだけで「今のインスタンスは大きすぎるのか、足りないのか」が根拠を持って言えるようになります。負荷試験の設計やインフラ構成・費用の見直しに専門的な支援が必要な場合は、Harmonic Societyのシステム開発・インフラ支援にご相談ください。
Harmonic Society
この記事の内容、自社の業務でも活かせそうですか?
ローカルLLM・AI・クラウドなどの技術導入を、要件整理からPoC・社内展開まで代表エンジニアが伴走します。オンライン対応・全国OK。まずは30分の無料相談から。売り込みはしません。
関連記事
Related / 9 articles
Notes & Insights
- プログラミング
DDoS攻撃の仕組みと対策入門|レイヤー別の防御とCDN・クラウドの活用
DDoS攻撃をボリューム型・プロトコル型・アプリ層に分けて仕組みを解説し、自前サーバーで防げない理由、CloudflareやAWS Shieldの標準防御、オリジンIPの隠し方、レートリミットとBot対策、攻撃を受けたときの初動、費用が跳ね上がるDenial of Walletへの備えまでわかります。
- プログラミング
WAFとは?仕組み・導入パターン・誤検知対策|Webアプリを攻撃から守る実践ガイド
WAFがファイアウォールやIDSと何が違うのか、シグネチャとマネージドルールの仕組み、Cloudflare WAF・AWS WAF・ModSecurityの比較、フォーム送信がブロックされる誤検知の調査と例外設定、ログ監視、WAFが代替できないことまで実践的に解説します。
- プログラミング
セキュリティヘッダー入門|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での設定例、確認方法を解説します。
- プログラミング
クラウドの通信費(Egress)入門|データ転送量課金の仕組みと転送コストを抑える設計
クラウドの「受信無料・送信有料」の原則、AZ間・リージョン間・インターネット向けの単価差、NATゲートウェイ処理料の罠、CDNで転送量を減らす方法、バックアップやログ転送の見落とし、請求書で転送料を特定する手順を解説。想定外の請求を防げます。
- プログラミング
秘密情報をGitに入れない仕組み|.gitignore・git-secrets・履歴から漏れた鍵の削除
APIキーや.envをGitにコミットしてしまう典型経路と、.gitignore・.env.exampleの運用、pre-commitでのgitleaks検知、GitHub secret scanningの活用、漏れた鍵の無効化と履歴書き換え(git filter-repo)の手順を解説。仕組みで再発を防げます。
- プログラミング
開発・ステージング・本番環境の分離設計|環境差分をなくす構成とアクセス制御
開発・ステージング・本番それぞれの目的と、構成をコードで揃える方法、環境別の設定注入、本番データを使わないテストデータ戦略、ステージングの保護(Basic認証・IP制限・noindex)、コストを抑える運用までを解説。環境差分による本番障害を防げます。
- プログラミング
ngrok・Cloudflare Tunnelでローカルを公開|Webhook開発とデモ環境の作り方
NAT内のローカル環境にStripeやLINEのWebhookを届けるトンネリングの仕組みを解説。ngrok・Cloudflare Tunnel・localtunnelの比較、固定ドメインと認証、リクエスト検査、公開時のセキュリティ、自宅サーバー公開への応用までわかります。
- プログラミング
ローカル開発環境のHTTPS化|mkcert・hostsファイル・自己署名証明書の正しい使い方
ローカル開発をHTTPS前提にすべき理由(Secure Cookie・Service Worker・OAuth)と、mkcertでローカルCAを作りhostsで独自ドメインを割り当ててVite・Next.js・Dockerで使う手順を解説。証明書警告を無視する癖の危険も理解できます。
- プログラミング
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営業日以内に返信します