LESSON 25分

ストーリー

高橋アーキテクトがホワイトボードに2つの線を描いた。

高橋アーキテクト
パフォーマンスを語るとき、いつも”速い”とか”遅い”と言うけど、何が速いのか? 2つの全く異なる指標がある
あなた
レイテンシとスループットですか?
高橋アーキテクト
そうだ。この2つを混同すると、間違った最適化をしてしまう。高速道路で例えてみよう。レイテンシは東京から大阪までの所要時間。スループットは1時間に何台の車が通れるか。全く別の話だろう?

レイテンシ(Latency)

レイテンシとは、リクエストを送ってからレスポンスを受け取るまでの時間です。

レイテンシの構成要素

// APIリクエストのレイテンシ内訳
interface LatencyBreakdown {
  dnsLookup: number;       // DNS解決: 1-50ms
  tcpHandshake: number;    // TCP接続: 1-100ms
  tlsHandshake: number;    // TLS/SSL: 1-100ms
  networkTransit: number;  // ネットワーク転送: 1-500ms
  serverProcessing: number; // サーバー処理: 1-5000ms
  responseTransfer: number; // レスポンス転送: 1-1000ms
}

// 典型的なWebアプリのレイテンシ目標
const LATENCY_TARGETS = {
  apiCall: 200,        // API呼び出し: 200ms以下
  pageLoad: 2000,      // ページ読み込み: 2秒以下
  dbQuery: 50,         // DBクエリ: 50ms以下
  cacheHit: 5,         // キャッシュヒット: 5ms以下
  searchResult: 500,   // 検索結果: 500ms以下
};

有名な数値(Latency Numbers Every Programmer Should Know)

操作時間比喩
L1キャッシュ参照0.5ns1秒
L2キャッシュ参照7ns14秒
メモリ参照100ns3分20秒
SSD読み取り150μs3.5日
HDD読み取り10ms8ヶ月
同一DC内ラウンドトリップ0.5ms11.5日
大陸間ラウンドトリップ150ms9.5年

スループット(Throughput)

スループットとは、単位時間あたりに処理できるリクエストの数です。

// スループットの計測例
interface ThroughputMetrics {
  requestsPerSecond: number; // RPS: 秒間リクエスト数
  transactionsPerSecond: number; // TPS: 秒間トランザクション数
  bytesPerSecond: number;   // BPS: 秒間転送量
}

// スループットの計算
function calculateThroughput(
  totalRequests: number,
  durationSeconds: number
): number {
  return totalRequests / durationSeconds; // RPS
}

// 例: 60秒間に3000リクエスト → 50 RPS
const rps = calculateThroughput(3000, 60); // 50

スループットに影響する要因

// リトルの法則: L = λ × W
// L: 同時処理数, λ: スループット, W: レイテンシ
function littlesLaw(
  concurrency: number,
  latencySeconds: number
): number {
  return concurrency / latencySeconds; // スループット(RPS)
}

// 例: 同時接続100、平均レイテンシ0.2秒
const throughput = littlesLaw(100, 0.2); // 500 RPS

レイテンシとスループットの関係

トレードオフの発生

レイテンシとスループットは独立した指標ですが、相互に影響し合います。

// 負荷が増えるとレイテンシが悪化する典型例
interface LoadProfile {
  rps: number;       // リクエスト/秒
  avgLatency: number; // 平均レイテンシ(ms)
  p99Latency: number; // 99パーセンタイルレイテンシ(ms)
}

const loadProfiles: LoadProfile[] = [
  { rps: 100,  avgLatency: 50,   p99Latency: 100 },
  { rps: 500,  avgLatency: 80,   p99Latency: 200 },
  { rps: 1000, avgLatency: 150,  p99Latency: 500 },
  { rps: 2000, avgLatency: 500,  p99Latency: 2000 },
  { rps: 3000, avgLatency: 2000, p99Latency: 10000 }, // 飽和点
];

飽和点(Saturation Point)

システムの処理能力の限界に近づくと、レイテンシが急激に悪化します。この境界が「飽和点」です。

レイテンシ
  │         ╱
  │        ╱
  │      ╱     ← 飽和点を超えると急激に悪化
  │    ╱
  │───────
  └─────────── スループット(RPS)

パーセンタイル(Percentile)

平均値だけでは真のパフォーマンスはわかりません。パーセンタイルで分布を理解します。

function calculatePercentile(
  sortedValues: number[],
  percentile: number
): number {
  const index = Math.ceil((percentile / 100) * sortedValues.length) - 1;
  return sortedValues[index];
}

// 使用例
const latencies = [10, 15, 20, 25, 30, 50, 80, 100, 200, 5000];
latencies.sort((a, b) => a - b);

const p50 = calculatePercentile(latencies, 50);  // 30ms  - 中央値
const p95 = calculatePercentile(latencies, 95);  // 200ms - 95%のユーザー
const p99 = calculatePercentile(latencies, 99);  // 5000ms - 99%のユーザー

// p99が異常に高い → テールレイテンシ問題
パーセンタイル意味重要度
p50(中央値)半数のリクエストの体験基本指標
p95大多数のユーザーの体験SLA指標
p99ほぼ全員の体験品質指標
p99.9最悪ケースに近い上位サービス向け

まとめ

ポイント内容
レイテンシリクエストからレスポンスまでの所要時間
スループット単位時間あたりの処理量(RPS)
リトルの法則L = λ × W で3指標が結びつく
飽和点処理能力の限界でレイテンシが急激に悪化
パーセンタイル平均値ではなくp50/p95/p99で評価する

チェックリスト

  • レイテンシとスループットの違いを説明できる
  • リトルの法則を使ってスループットを計算できる
  • パーセンタイルの重要性を理解した
  • 飽和点の概念を理解した

次のステップへ

次は「ボトルネックの特定方法」を学びます。CPU、I/O、メモリ、ネットワークのどこが制約になっているかを見極める技術です。


推定読了時間: 25分