ストーリー
テストが終わり、画面に大量の数値が表示された。
高橋アーキテクトが指差した。
パーセンタイルの読み方
k6出力の例
http_req_duration..........: avg=85ms min=12ms med=62ms max=4521ms
p(90)=142ms p(95)=238ms p(99)=892ms
http_req_failed............: 0.23% ✗ 69 ✓ 29931
http_reqs..................: 30000 500.0/s
vus........................: 50 min=50 max=50
各パーセンタイルが語ること
interface TestResultAnalysis {
p50: {
value: number; // 62ms
meaning: '半数のユーザーの体験。"普通の"パフォーマンス';
action: 'SLOの基本指標として使う';
};
p95: {
value: number; // 238ms
meaning: '大多数のユーザーの体験。20人に1人はこれより遅い';
action: 'SLAに使う最も一般的な指標';
};
p99: {
value: number; // 892ms
meaning: 'ほぼ全員の体験。テールレイテンシの指標';
action: '外れ値の原因調査が必要か判断';
};
}
p95とp99の差が大きい場合
// p95 = 238ms, p99 = 892ms → 約3.7倍の差
// これはテールレイテンシ問題の兆候
const tailLatencyIndicators = {
healthyRatio: 'p99 / p95 < 2', // 2倍以内なら健全
warningRatio: 'p99 / p95 = 2-5', // 2-5倍は要注意
criticalRatio: 'p99 / p95 > 5', // 5倍以上は即調査
commonCauses: [
'GCの停止(Stop the World)',
'特定のDBクエリが遅い(スロークエリ)',
'外部APIのタイムアウト',
'コネクションプールの枯渇',
'ディスクI/Oのスパイク',
],
};
レスポンスタイム分布の分析
リクエスト数
│
│ ██
│ ████
│ ██████
│ ████████
│ ████████████
│ ████████████████ ██ ← テールレイテンシ
│ ████████████████████████
└──────────────────────────────────────── レスポンスタイム
0 50 100 200 300 500 1000 5000ms
正常な分布は左に偏った形(ほとんどが短時間で完了)。右に長い尾(テール)がある場合は要調査です。
エラー分析
// エラーの分類と対策
interface ErrorAnalysis {
// HTTP ステータス別
statusCodes: {
'4xx': {
rate: number; // 0.1%
meaning: 'クライアントエラー(テストデータの問題かも)';
action: 'テストシナリオの確認';
};
'5xx': {
rate: number; // 0.13%
meaning: 'サーバーエラー(アプリケーションのバグ or リソース不足)';
action: 'サーバーログの調査';
};
timeout: {
rate: number; // 0.02%
meaning: 'タイムアウト(コネクション枯渇 or 処理遅延)';
action: 'コネクションプール設定の確認';
};
};
}
// エラー率の閾値
const errorThresholds = {
acceptable: 0.1, // 0.1%以下: 許容範囲
warning: 0.5, // 0.5%以下: 要注意
critical: 1.0, // 1%以上: 即座に対処
};
レポートの作成
// 負荷テストレポートのテンプレート
interface LoadTestReport {
// 1. テスト概要
summary: {
testDate: string;
testType: string; // ロード/ストレス/スパイク/ソーク
duration: string;
maxVUs: number;
totalRequests: number;
};
// 2. 結果サマリー
results: {
throughput: number; // 実測RPS
latency: {
p50: number;
p95: number;
p99: number;
};
errorRate: number;
};
// 3. SLO判定
sloCheck: {
passed: boolean;
details: SLOCheckDetail[];
};
// 4. ボトルネック分析
bottlenecks: {
identified: string[];
evidence: string[];
};
// 5. 改善提案
recommendations: string[];
}
レポート例
=== 負荷テストレポート ===
テスト日: 2026-02-10
テスト種類: ロードテスト
テスト時間: 16分(2m ramp-up + 10m steady + 2m ramp-down + 2m cool-down)
最大VU: 100
--- 結果サマリー ---
スループット: 2,850 RPS(目標: 3,000 RPS)→ 未達
p50: 62ms(目標: 100ms以下)→ 達成
p95: 238ms(目標: 300ms以下)→ 達成
p99: 892ms(目標: 500ms以下)→ 未達
エラー率: 0.23%(目標: 0.1%以下)→ 未達
--- SLO判定: 不合格 ---
--- ボトルネック ---
1. DBコネクションプールの枯渇(max=20 → 30に増加推奨)
2. /api/search のスロークエリ(p99=1200ms)
--- 改善提案 ---
1. DBコネクションプール上限を30に増加
2. 検索クエリにインデックスを追加
3. 検索結果のキャッシュTTLを5分に設定
4. 改善後に再テスト実施
まとめ
| ポイント | 内容 |
|---|---|
| p50/p95/p99 | まず3つのパーセンタイルを確認する |
| テールレイテンシ | p99/p95の比率で異常を検出 |
| エラー分析 | ステータスコード別に原因を分類 |
| レポート | 結果サマリー → SLO判定 → ボトルネック → 改善提案 |
チェックリスト
- パーセンタイルの読み方を理解した
- テールレイテンシの原因を推測できる
- エラー率の分析方法を把握した
- 負荷テストレポートを作成できる
次のステップへ
次は演習です。実際に負荷テストのシナリオを書いて、結果を分析してみましょう。
推定読了時間: 25分