
タイムアウトはどこで起きているか|多段構成の切り分け
「さっきの画面、しばらく待たされた末にエラーになったんですけど」——保守運用をしていると、この「タイムアウトしました」という報告に何度も出くわしますよね。やっかいなのは、時間切れは一つの場所で起きるのに、リクエストはいくつもの段を経由していることです。ブラウザ、ロードバランサー、nginx、アプリ(php-fpmなど)、DB、外部API——どこか一段で時間切れになっただけでも、ユーザーには同じ「タイムアウト」に見えます。
だから、どこの数字を延ばせばいいのか分からず、ついあちこちのタイムアウト値を手当たり次第に延ばしてしまいがちです。でも、それは詰まりの元を奥に押し込むだけで、根っこは残ります。まず必要なのは、「今回はどの段で時間切れになったのか」を一つに絞ることです。
この記事では、多段構成のタイムアウトを「一番短い制限が先に切れる」という考え方を軸に、手前(ユーザー側)から奥(DB・外部API)へ順番に、どの層で切れたかをログから絞る手順を一緒に整理します。構成(Apache、nginx+php-fpm、ロードバランサー+アプリサーバーなど)で細部は変わりますが、考え方はそのまま使えます。
結論:多段構成では、経路の中で一番短いタイムアウトが最初に発火します。だから直すべきは「一番短い値」ではなく、「実際に時間切れを起こした一段」です。手順は、①いつ・どのくらい待たされて切れたか(体感時間)を押さえる → ②各層のログで「timed out」の記録が出ている段を探す → ③その段のタイムアウト値と、上流の遅さのどちらが原因かを見分ける。値を延ばすのは応急処置と割り切り、本筋は「なぜその段が待たされたか」に置きます。むやみに全部の値を延ばすと、遅い処理が居座って受け口を長くふさぎ、かえって全体が詰まります。
何が起きているか:タイムアウトは「一番せっかちな段」が先に切れる
タイムアウトは、「決めた時間内に相手が返してこなかったら、待つのをやめて切る」という約束事です。多段構成では、この約束事が段ごとに別々に設定されています。ざっくり並べると、こんな段があります。
- ブラウザ:ユーザーの手元。読み込みが長すぎると、ユーザー自身が待ちきれずに再読み込みしたり離脱したりします。
- ロードバランサー/リバースプロキシ(nginx等):手前で受けて後ろに取り次ぐ段。「後ろが時間内に返さなければ504を返す」制限を持ちます(
proxy_read_timeout/fastcgi_read_timeoutなど)。 - アプリ(php-fpm等):処理そのものの時間制限(PHPなら
max_execution_timeなど)。 - DB・外部API:さらに奥。クエリの実行時間制限や、外部APIを呼ぶときの接続・応答の待ち時間。
ここで大事なのは、一番短い制限を持つ段が、最初に時間切れになるということです。たとえばアプリの処理は60秒まで許されていても、手前のnginxが30秒で切る設定なら、ユーザーには30秒で504が返り、アプリはまだ裏で処理を続けている——という食い違いが起きます。逆に、nginxは長く待つのにDBのクエリ制限が短ければ、切れるのはDBの段です。
つまり「タイムアウトした」という一言の裏では、その経路でいちばんせっかちな段が犯人役になっています。次から、その一段を絞る順番を見ていきます。
手前から奥へ、どの段で切れたかを絞る

ポイントは、どの段のタイムアウト値が発火したかを先に特定してから、値をいじることです。奥からいきなり延ばすと、原因でない段まで触って回ることになります。
① 「どのくらい待って切れたか」を押さえる
最初の手がかりは、時間切れになるまでの体感時間です。ここが、どの段が切れたかを当てる近道になります。
- 報告者に「だいたい何秒くらい待って、そのあとエラーになったか」を聞く。あるいは自分で再現して、ストップウォッチ代わりに秒数をつかみます。
- その秒数を、各段のタイムアウト値と照らす。たとえば「いつも30秒ちょうどで切れる」なら、30秒に設定された段(多くはプロキシの
proxy_read_timeoutなど)が怪しい。「60秒で切れる」なら別の段。きっかり同じ秒数で切れるなら、それは「上限に達して切られた」サインで、犯人の段を強く示します。 - 秒数がバラバラ(10秒だったり50秒だったり)なら、固定の上限で切れているのではなく、そのときどきの遅さ(上流の混み具合)に引っぱられている可能性が高い。値の問題より、遅さの問題を疑います。
「何秒で切れるか」を先に押さえるだけで、次に開くログの当たりがつきます。
② 各層のログで「切った段」を探す
体感時間で当たりをつけたら、その段のログに時間切れの記録が出ているかを確かめます。切った側は、たいてい正直に記録を残しています。
- プロキシ(nginx等)のエラーログ:
upstream timed out (110: Connection timed out) while reading response headerのような行が出ていれば、nginxが「後ろが時間内に返さない」と判断して切ったサインです。これが出ているなら、ユーザーに返った504はこの段が出したものです。 - アプリ(php-fpm等)のログ:処理時間の上限(PHPなら
max_execution_time)に達した場合、Maximum execution time ... exceededのような記録が出ます。これが出ていれば、アプリ自身が自分の処理を打ち切った段です。 - DB・外部API:クエリ実行時間の上限に達した記録や、外部API呼び出しでの接続・読み取りの待ち超過。アプリのログに「DB接続が切れた」「APIから応答がなかった」といった痕跡が残ることも多いです。
ここで注意したいのは、「切った段」と「遅かった段」は別のことがあるという点です。nginxが504を出していても、遅さの元はその奥のDBかもしれません。nginxのログは「後ろが時間内に返さなかった」と教えてくれているだけで、なぜ返さなかったかは、さらに奥を見て初めて分かります。
ここで一呼吸。秒数を聞いてログを開くのは遠回りに感じるかもしれませんが、「どの段で切れたか」を先に知るための一番の近道です。焦って全部の値を延ばす前にログを見た、その判断がすでに落ち着いた一歩です。
③ 「値が短すぎる」のか「上流が遅い」のかを見分ける
切った段が分かったら、最後に原因の向きを見分けます。ここを取り違えると、直したつもりが逆効果になります。
- 値が短すぎる(設定の問題):処理は正常なのに、正当にかかる時間より短い上限が設定されている場合。たとえば、もともと数十秒かかることが分かっている集計処理に、30秒の上限がかかっているようなケース。この場合は、その段の値を、実態に合った長さへ見直すのが妥当です。
- 上流が遅い(詰まりの問題):値は妥当なのに、上流(DBや外部API)がいつもより遅くて間に合っていない場合。重いSQL、ロック待ち、外部APIの障害などが元です。この場合、値を延ばしても遅い処理が居座るだけで、受け口を長くふさぎ、かえって他のリクエストまで巻き込みます。本筋は上流の遅さを解消することです。
- 見分けの目安:「前は普通に返っていたのに、最近だけ切れるようになった」なら、上流が遅くなった疑いが濃い(値は昔から同じはず)。「その処理は昔から重く、いつも上限ぎりぎり」なら、値の見直しと処理の軽量化を両輪で考えます。
値をいじる前に、いまの値と状態をメモしてから動きます。「元に戻せる状態」を保ったまま、一段ずつ確かめます。
具体例:「30秒ちょうどで切れる」を追う
よくある報告を、順番に切り分けてみます。
- ①体感時間:ユーザーは「30秒くらい待つと必ずエラーになる」と言う。きっかり同じ秒数なので、固定の上限に達して切られている疑い。
- ②ログ:nginxのエラーログに、その時刻の
upstream timed out ... while reading response headerが並ぶ。切ったのはnginxの段(proxy_read_timeout30秒)と判明。一方、php-fpmのログには「実行時間超過」の記録はない=アプリはまだ返そうと動いていた。 - ③原因の向き:その画面はある集計レポートで、データが増えて処理が40秒ほどかかるようになっていた。処理自体は正常で、30秒の上限のほうが実態に合わなくなっていた(=値が短すぎる側)。ただし「40秒かかること自体が重い」ので、上流の重いSQLも同時に見直す。
- 対処:まずnginx側の値を実態に合わせて調整しつつ、根本は集計SQLの軽量化(取得件数の制限・インデックス見直し)に置いた。値だけ延ばして終わりにしない。
もし最初に「とりあえず全部のタイムアウトを延ばす」をしていたら、一時的に表示は戻っても、データが増えるたびにまた同じところで切れ、しかも重い処理が長く居座って他の画面まで遅くしていたはずです。「どの段が・なぜ切れたか」をたどれたからこそ、次に活きる直し方にたどり着けました。
影響:切り分けの順番を持つと、何が変わるか
タイムアウトの切り分け順を1枚持っておくと、直す力そのものより先に、焦りと手戻りが減ります。
- 「どこの数字を延ばそう」と手を動かす前に、「今回はどの段が切ったのか」と一度立ち止まれる。
- 体感時間(きっかり同じか、バラバラか)で、「値の問題」か「遅さの問題」かの見当がつく。
- 関係ない段の値まで延ばして回らずに済み、「たまたま直った」を「切れた段が分かって直った」に変えられる。
- 値を延ばすだけの対症療法に逃げず、上流の遅さという本丸に向かえる。
逆に、毎回いきなり全部の値を延ばしていると、詰まりが奥に溜まっていき、ある日まとめて大きく効いてきます。順番は、その日の自分を助ける道具です。
明日やること:自分の現場の「タイムアウト一覧」を1枚書く
立派な資料は要りません。明日できる、いちばん小さな一歩はこれです。
- 自分が担当するサイトで、リクエストがユーザー→どこ→どこと流れるかを書き出す(例:ブラウザ → nginx → php-fpm → MySQL、途中に外部API)。
- それぞれの段のいまのタイムアウト値を1行ずつ控える(nginxの
proxy_read_timeout/fastcgi_read_timeout、PHPのmax_execution_time、DBやAPIクライアントの待ち時間など)。値が分からない段は「未確認」と書いておくだけでも十分です。 - その一覧を眺めて、一番短い値がどこかを確認する。そこが「まず切れる段」の候補です。
- あわせて、各段のタイムアウトログの場所と、時間切れを示す文言を1行メモする(nginxの
upstream timed out、PHPのMaximum execution timeなど)。 - 次にタイムアウトの報告が来たら、体感時間 → この一覧 → ログ、の順にたどる。効いた段と原因を書き足していく。
きれいに描かなくて大丈夫です。「どの段が、何秒で、どんなログを残して切るか」の一覧が1枚あるだけで、次の自分(や引き継ぐ人)が、全部の値を手当たり次第に延ばすループに迷い込まずに済みます。
タイムアウト切り分けチェックリスト
切り分けに着手するとき、これだけ確認できているかを見る項目です。コピーして、自分のメモに当ててみてください。全部を毎回そろえる必要はありません。
まず外せない最低ラインはこの3つです。急いでいても、ここだけは押さえます。
- 【最低ライン】値をいじる前に、「だいたい何秒で切れたか」を押さえたか
- 【最低ライン】各段のログで、「timed out」など時間切れを記録している段を探したか
- 【最低ライン】「値が短すぎる」のか「上流が遅い」のかを見分けたか
次の項目は、手前で片づかないとき・原因が奥にありそうなときに追加で確認します。当てはまらなければ飛ばして大丈夫です。
- きっかり同じ秒数で切れるか(固定の上限に達したサイン)/バラバラか(遅さに引っぱられているサイン)を見たか
- nginx(プロキシ)の
upstream timed outが出ているか、それはどの段を指すか確かめたか - アプリ(php-fpm等)が自分の処理を打ち切っていないか(実行時間超過のログ)を見たか
- 「切った段」と「遅かった段」を混同していないか(504の奥にDB・外部APIの遅さがないか)
- 「前は返っていたのに最近だけ切れる」か「昔から上限ぎりぎり」かで、値と遅さのどちらを直すか決めたか
- 値を延ばすのは応急処置と割り切り、上流の遅さの解消を本筋に置いたか
- 設定値を触る前に、いまの値・状態をメモして戻せるようにしたか
全部に○が付かなくても大丈夫です。最低ラインの3つ、とくに「値をいじる前に、どの段が切ったかを一つに絞る」さえ押さえられれば、手当たり次第に数字を延ばして消耗するより、ずっと確かな一歩になります。
よければ、こちらも
タイムアウトの切り分けは、「どの段で・なぜ待たされたか」をたどるほど楽になります。近い5xxの見方や、奥の遅さの調べ方をセットにしておくと、次の「タイムアウトしました」がだいぶ軽くなります。
- 502・504エラーの切り分け|nginx・php-fpm・上流の順に見る:504(時間切れ)を含む5xxを、nginxのログから手前→奥へ切り分ける手順です。この記事と対にすると効きます。
- DBコネクション枯渇・デッドロックの見つけ方と一次対処:タイムアウトの奥でよくある「上流のDBが詰まる」パターンを、見つけ方から一次対処まで整理しています。
- 外部API連携の不具合|相手側か自分側かを切り分ける:外部APIの待ちで切れるとき、遅いのは相手か自分かを見分ける進め方です。

タイムアウトがこわいのは、「時間切れ」という結果は一つなのに、切れうる場所がいくつもあって、どこを直せばいいのか見えないからです。でも、「一番せっかちな段が先に切れる」と考えて、体感時間からログへ順にたどると決めるだけで、霧はかなり晴れます。多くの場合、全部の値がおかしいわけではなく、ただ一段だけが、実態より短い時間で——あるいは奥の遅さに引っぱられて——先に切れていただけです。
今日は、自分の現場の「タイムアウト一覧」を1枚書いてみるところからで十分です。その1枚が、次の「タイムアウトしました」を、総当たりではなく手順に変えてくれます。
ほかの実務ヒントは記事一覧からどうぞ。保守運用の小さな備えを、メールでも少しずつお届けしています。