ITエンジニア必読:タイムアウトの全貌と現場で使える設計・運用ガイド
はじめに — なぜタイムアウトが重要か
「タイムアウト」は単なる待ち時間の打ち切りではなく、分散システムやネットワーク、アプリケーションの安定性・可用性・セキュリティに直結する重要な設計要素です。適切に設計されたタイムアウトはリソース枯渇を防ぎ、応答性を保ち、障害の局所化を助けます。一方、短すぎる・長すぎる設定はそれぞれサービス断や過剰なリトライ、DoSにつながり得ます。本稿ではタイムアウトの種類、原理、実装例、運用・監視方法、ベストプラクティスまでを詳細に解説します。
タイムアウトの基本概念と分類
- クライアントタイムアウト:クライアントがリクエスト送信後に応答を待つ最大時間。ブラウザやAPIクライアントで設定。
- サーバータイムアウト:サーバーがリクエスト処理に割く最大時間(例:HTTPリクエストの処理時間制限、DBのstatement_timeout)。
- ネットワーク/トランスポートの再送タイムアウト(RTO):TCPなどでパケットの再送を行うための時間(TCP RTOはRFC 6298で規定に基づき推奨アルゴリズムあり)。
- アイドル/キープアライブタイムアウト:接続が一定時間アイドル状態なら切断する。ロードバランサーやプロキシ、TCPで一般的。
- DNSタイムアウト:名前解決の応答待ち時間。複数のリトライやフェイルオーバーポリシーと組み合わせる。
- セッション/認証のタイムアウト:ユーザーの認証有効期間やセッションの無効化時間(OWASPが推奨する要件あり)。
タイムアウトの設計原則
- 短すぎない/長すぎない:ユーザー体験とリソース消費のバランス。インタラクティブな操作は短め、バッチ処理は長めに。
- 可観測性をセットに:タイムアウト発生をログ・メトリクスで検知できるようにする。原因がネットワークか処理遅延か切り分け可能にする。
- 段階的なエラーハンドリング:即時エラー、リトライ(指数バックオフ+ジッタ)、サーキットブレーカーなどを組み合わせる。
- 明示的な契約で管理:APIのSLAやタイムアウト値はドキュメント化し、クライアントと合意する。
実装で注意すべき具体項目
以下は現場でしばしば問題になるポイントと対処法です。
- TCP RTO とアプリケーションタイムアウトの乖離
TCPの再送・切断とアプリケーション層のタイムアウトが食い違うと、アプリはタイムアウトしたのにTCP接続が生きていてリソースを消費し続けることがあります。OSやミドルウェアのkeepalive設定やアプリケーションのソケットタイムアウトを揃えることが重要です。
- リトライの副作用
短めのタイムアウト+同期的な自動リトライはスパイクを拡大し、サービス全体を不安定にします。指数バックオフ+ジッタを必ず導入し、最大再試行回数を設けます(ライブラリ:Resilience4j等)。
- ロードバランサー/プロキシのアイドルタイムアウト
AWS ELBやNginxなどはデフォルトでアイドル切断を行うため、WebSocketや長時間処理には調整が必要です。クライアント・サーバ・LBの3者で整合させること。
- DBのタイムアウト
長時間のクエリはDB接続を占有し、他のクエリをブロックします。PostgreSQLのstatement_timeoutやMySQLのinnodb_lock_wait_timeoutなどを適切に設定し、アプリ側でもクエリタイムアウトを持たせる。
リトライ戦略:指数バックオフとジッタ
単純な固定間隔リトライは同時障害時に再試行が同期してしまい、二次障害を引き起こします。一般的には指数バックオフ(base * 2^n)にランダムなジッタ(ばらつき)を加え、分散させるのが良いプラクティスです。AWSのアーキテクチャブログやGoogle SREの推奨にも類似の手法が紹介されています。
監視と可観測性
タイムアウトに関する監視は多面的に行います。
- リクエストレイテンシ分布(P50/P95/P99)
- タイムアウト発生回数と比率(全リクエストに対する割合)
- 関連するインフラのメトリクス(CPU, メモリ, ネットワークパケットロス)
- アプリケーションログでのタイムアウト例外のスタックトレース集計
Prometheus+Grafanaやログ集約(ELK/EFK)を用い、アラート基準を明確に定義します。例えばP95レイテンシがSLAの75%を超えたら通知、タイムアウト率が0.5%以上ならインシデントといったポリシーです。
セキュリティ観点での注意点
- 長すぎるタイムアウトは接続を長時間確保し、リソース枯渇を狙うDoS攻撃の足掛かりになります。特に認証・セッション関連は短く保つ。
- 短すぎるタイムアウトは認証フローやCSRF防御で誤検知を招き、ユーザビリティ低下や誤った再認証を誘発する可能性があるため、セキュリティと利便性のバランスが必要です。
- リトライの上限を設けないと、攻撃時に自ら攻撃を助長する結果になります。
具体的な設定例とガイドライン
- ブラウザ/APIクライアント:一般的なAPIコールは5〜30秒。ユーザ操作のレスポンスは1〜3秒を目安に。長時間処理は非同期にしてポーリングやWebSocketで通知する。
- ロードバランサー(例:AWS ALB/ELB):デフォルトidle timeoutを理解し、WebSocketなどには長めに設定。逆に大量接続を捌く用途での長時間アイドルは避ける。
- データベース:OLTPの短いクエリは数秒〜数十秒、バッチ処理は個別に長めに設定。statement_timeout等で意図せぬ長時間クエリを遮断。
- TCPキープアライブ:OSデフォルト(例:Linuxは長め)が合わない場合は調整。プロキシ越しの接続維持等で重要。
トラブルシューティングの手順
- 発生箇所の特定:クライアント、ネットワーク、LB、アプリ、DBのどこでタイムアウトが発生しているかログとメトリクスで切り分ける。
- 再現と計測:負荷・遅延を模擬して閾値を超える状況を再現し、どのコンポーネントがボトルネックになるかを測定。
- 対処と検証:タイムアウトの調整、リトライポリシー変更、キャパシティ増強、クエリ最適化などを順に適用して効果を検証。
まとめ — 実践的なチェックリスト
- すべてのレイヤー(クライアント、アプリ、DB、ネットワーク)に明確なタイムアウト値を設定しているか。
- リトライは指数バックオフ+ジッタ、最大試行回数を設定しているか。
- タイムアウト発生時のログ・メトリクスを収集し、アラート化しているか。
- ロードバランサーやOSのTCP設定とアプリのタイムアウトが整合しているか。
- セキュリティとユーザビリティのバランスを評価し、ドキュメント化しているか。
参考文献
- RFC 6298 - Computing TCP's Retransmission Timer
- RFC 793 - Transmission Control Protocol
- RFC 1035 - Domain names - Implementation and specification
- OWASP Session Management Cheat Sheet
- PostgreSQL: statement_timeout
- MySQL: wait_timeout
- MDN: AbortController(ブラウザでのタイムアウト制御)
- AWS Blog: Exponential Backoff And Jitter
- Prometheus(監視)
- NGINX: Tuning Guide(keepalive/timeout関連)


