2026年5月25日
2026年5月25日
Apacheのタイムアウト設定を最適化する方法|Timeout・RequestReadTimeout・ProxyTimeoutの決め方
Apache のタイムアウトは1つの値ではなく、接続の待ち時間を決める Timeout、リクエストの受信を見張る RequestReadTimeout、PHP-FPM などの裏側の処理を待つ ProxyTimeout などに分かれています。最適化の基本は「長くすればよい」ではなく、それぞれの役割に合った値にし、CDN から PHP までの各段のタイムアウトの順序をそろえることです。この記事では、各設定の意味と目安、WordPress で処理が途中で切れるときの切り分け方を説明します。
PHP の max_execution_time を中心にした設定は別の記事で扱うため、ここでは Apache 側の設定と、前後の段との関係に焦点を当てます。
Apache のタイムアウトに関係する設定
Timeout
Timeout は、リクエストの受信やレスポンスの送信の途中で、データのやり取りが止まったときに待つ秒数です。Apache 2.4 の既定値は 60 秒ですが、Debian/Ubuntu 系の標準の apache2.conf には 300 が書かれていることがあります。現在の値は設定ファイルを検索すると分かります。
# Debian/Ubuntu系
grep -Rn "^\s*Timeout" /etc/apache2/
# RHEL/AlmaLinux系(書かれていなければ既定値で動いている)
grep -Rn "^\s*Timeout" /etc/httpd/
Timeout は「1つのリクエスト全体の制限時間」ではない点に注意してください。データが少しずつでも流れていれば待ち時間はその都度リセットされます。また、後述の ProxyTimeout を指定していない場合は、裏側のサーバーを待つ時間にもこの値が使われます。
値を大きくすると、通信が止まった接続をいつまでも抱えることになり、混雑時に処理枠を圧迫します。通常のサイトなら 60 秒前後で足ります。300 が書かれている場合でも、すぐに下げる必要はありませんが、長い処理を許すための値なのか、単に標準のままなのかを把握しておくと後の調整がしやすくなります。
KeepAliveTimeout
KeepAliveTimeout は、1つのリクエストを返し終えたあと、同じ接続で次のリクエストを待つ秒数です。既定は 5 秒です。名前は似ていますが Timeout とは役割が違い、処理が途中で切れる問題には関係しません。prefork MPM では長くすると処理枠を占有しやすいため短めにします。
RequestReadTimeout(mod_reqtimeout)
RequestReadTimeout は、クライアントからリクエストのヘッダーと本文を受け取るまでの時間と、最低限の転送速度を決めます。データを極端にゆっくり送り続けて接続を占有する攻撃(Slowloris など)への主な対策になります。Apache 2.4 では mod_reqtimeout が有効になっていれば既定の値で動いており、Debian/Ubuntu 系では /etc/apache2/mods-available/reqtimeout.conf に設定があります。
<IfModule reqtimeout_module>
RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500
</IfModule>
header=20-40,MinRate=500 は、ヘッダーの受信を最初に 20 秒待ち、500 バイト/秒以上のペースで届いていれば最大 40 秒まで延ばす、という意味です。この制限にかかると、Apache は 408 Request Timeout を返します。
回線の遅いスマートフォンから大きな画像をアップロードすると、本文の受信がこの制限にかかることがあります。メディアのアップロードだけが 408 で失敗する場合は、body の値を少し緩めることを検討します。ただし無効にはしないでください。
ProxyTimeout と PHP-FPM の待ち時間
PHP-FPM と mod_proxy_fcgi で連携している場合や、Apache をリバースプロキシとして使っている場合は、裏側の処理が返ってくるまで待つ時間が ProxyTimeout で決まります。指定がなければ Timeout の値が使われます。
<VirtualHost *:443>
ServerName example.com
ProxyTimeout 120
</VirtualHost>
この時間を過ぎると、Apache は 504 Gateway Timeout などのエラーを返し、エラーログにはタイムアウトで裏側の処理を打ち切った旨のメッセージが残ります。PHP の処理そのものは裏で動き続けていることがある点も覚えておいてください。
ProxyTimeout はサーバー全体か VirtualHost に書く設定で、.htaccess や <Location> には書けません。Timeout も同様です。特定のパスだけ長くしたい場合は、管理用に別の VirtualHost を用意するなどの工夫が必要になり、設定が複雑になります。
各段のタイムアウトの順序をそろえる
WordPress のリクエストは、次のように複数の段を通ります。
ブラウザ → CDN → ロードバランサー → Apache → PHP-FPM → PHP スクリプト
それぞれの段にタイムアウトがあり、最も短いものが最初に切れます。目安として、内側ほど短く、外側ほど長くなるように並べます。
- PHP の
max_execution_time(例:60 秒) - PHP-FPM の
request_terminate_timeout(例:90 秒。既定の 0 は無制限) - Apache の
ProxyTimeout(例:120 秒) - ロードバランサーのアイドルタイムアウト(例:130 秒)
- CDN のオリジン応答の待ち時間(サービスとプランで上限が決まっていることが多い)
この順にしておくと、処理が長すぎたときは内側の PHP が先にエラーを出して止まり、エラーログに原因が残ります。逆に Apache やロードバランサーが先に切ると、ブラウザには 502 や 504 が返るだけで、PHP は裏で処理を続け、何が起きたのかが分かりにくくなります。
CDN やロードバランサーの待ち時間には、利用者が変えられない上限があることがあります。AWS の Application Load Balancer のアイドルタイムアウトは既定で 60 秒、Cloudflare もプロキシ経由のオリジン応答に上限がありますが、値やプランごとの扱いは変わることがあるため、各サービスのドキュメントで確認してください(2026年10月現在)。外側の上限を超える処理は、Apache 側の値を上げても完了しません。
なお PHP の max_execution_time は、Linux ではデータベースの問い合わせや外部 API の待ち時間を含まない場合があります。PHP 側では制限内に見えても、全体の時間は Apache の待ち時間を超えることがあるのはこのためです。
処理が途中で切れるときの切り分け
インポート、バックアップ、画像の一括再生成などが途中で止まる場合は、どの段が切ったのかを先に確かめます。可能性の高い順に確認します。
- ブラウザに表示されたエラーを見る:CDN の独自のエラーページなら CDN の待ち時間、504 なら Apache かロードバランサー、白い画面や PHP の Fatal error なら PHP 側を疑います。
- Apache のエラーログを見る:Debian 系は
/var/log/apache2/error.log、RHEL 系は/var/log/httpd/error_logです。タイムアウトに関するメッセージが該当する時刻に出ていれば、Apache のProxyTimeout(またはTimeout)で切れています。 - PHP-FPM のログを見る:
request_terminate_timeoutで打ち切られると、ワーカーを終了させた旨が PHP-FPM のログに記録されます。 - WordPress のデバッグログを見る:
WP_DEBUG_LOGを有効にしている場合、wp-content/debug.logに Maximum execution time の Fatal error があれば PHP の制限です。
アクセスログに処理時間(%D)を記録していれば、止まったリクエストが何秒で終わったかが分かり、どの設定値と一致するかで判断しやすくなります。手元からは curl でも時間を測れます。
curl -s -o /dev/null -w "status=%{http_code} total=%{time_total}s\n" https://example.com/
長い処理はタイムアウトを延ばす前に分ける
タイムアウトを延ばすと、その処理は通るようになりますが、サイト全体で長く待つ接続が増え、混雑時や攻撃を受けたときに処理枠が埋まりやすくなります。時間のかかる作業は、Web のリクエストから切り離すほうが安定します。
- インポートや置換、画像の再生成は WP-CLI で実行する(SSH からの実行は Apache のタイムアウトの影響を受けません)
- 定期的な重い処理は、wp-cron をサーバーの cron から呼ぶ形にし、処理を小分けにする
- プラグインに分割実行や非同期実行の設定があれば、それを使う
どうしても Web 経由で長い処理が必要な場合は、管理画面用の VirtualHost だけ ProxyTimeout を長くするなど、影響の範囲を絞ってください。
設定を変更して反映する
設定ファイルを編集する前にバックアップを取り、変更後は文法を確認してから反映します。本番に適用する前に、ステージング環境で該当の処理が通るかを試すと安心です。
sudo cp /etc/apache2/apache2.conf ~/apache2.conf.bak-$(date +%F)
sudo apache2ctl configtest
sudo systemctl reload apache2
PHP-FPM の request_terminate_timeout を変えた場合は、PHP-FPM 側の reload も必要です。
まとめ
Timeoutは通信が止まったときの待ち時間で、リクエスト全体の制限時間ではないKeepAliveTimeoutは接続の使い回しの待ち時間で、処理が切れる問題とは別物RequestReadTimeoutは低速攻撃への対策。408 が出るときだけ緩め、無効にはしないProxyTimeoutは PHP-FPM などの裏側を待つ時間。未指定ならTimeoutが使われる- 内側の PHP ほど短く、外側の CDN ほど長くなるように各段の値を並べる
- 長い処理はタイムアウトを延ばす前に WP-CLI や cron へ切り離す