2026年7月30日
2026年7月30日
Apacheのworker/event MPMでスレッド数を調整する方法(MaxRequestWorkers・ThreadsPerChild)
Apache 2.4のevent MPMとworker MPMは、1つの子プロセスの中で複数のスレッドを動かし、1スレッドで1つのリクエストを処理します。同時に処理できるリクエスト数の上限は「子プロセスの数 × 1プロセスあたりのスレッド数」で決まり、これを設定するのが MaxRequestWorkers と ThreadsPerChild などのディレクティブです。
この記事では、これらのディレクティブの関係、上限の見積もり方、設定の書き場所と反映方法、混み具合の確かめ方を説明します。設定とエラー表示は2026年10月時点のDebian 13(Apache 2.4.69、event MPM)で確かめています。
古い記事にある MaxClients と MaxRequestsPerChild は、Apache 2.4ではそれぞれ MaxRequestWorkers と MaxConnectionsPerChild に名前が変わりました。古い名前も受け付けられますが、新しい名前で書きます。
使っているMPMを確かめる
スレッドの設定が効くのはevent MPMとworker MPMです。prefork MPMはスレッドを使わず、1プロセスで1リクエストを処理するので、この記事の ThreadsPerChild などは使いません。
# Debian/Ubuntu
sudo apache2ctl -V | grep -i mpm
# RHEL系(AlmaLinux、Rocky Linuxなど)
sudo httpd -V | grep -i mpm
Server MPM: event のように表示されます。2026年10月時点のDebian/Ubuntuの apache2 パッケージは、標準でevent MPMを使います。
ただし、Debian/Ubuntuで libapache2-mod-php(mod_php)を入れると、MPMはpreforkに切り替わります。mod_phpはスレッドを使うMPMと一緒に使えないためです。event MPMでPHP(WordPressなど)を動かすには、PHP-FPMを使います。手順はApacheでPHP-FPMを使う設定を、MPMの違いはApacheのworkerとpreforkの違いを参照してください。
スレッド数を決めるディレクティブ
| ディレクティブ | 意味 | Apacheの既定値 | Debianの設定ファイルの値 |
|---|---|---|---|
ServerLimit |
子プロセス数の上限 | 16 | (記載なし) |
ThreadLimit |
ThreadsPerChild に設定できる値の上限 |
64 | 64 |
ThreadsPerChild |
1つの子プロセスが作るスレッド数 | 25 | 25 |
MaxRequestWorkers |
同時に処理するリクエスト数の上限(全スレッド数の上限) | ServerLimit × ThreadsPerChild(16 × 25 = 400) |
150 |
StartServers |
起動時に作る子プロセス数 | 3 | 2 |
MinSpareThreads |
待機スレッドがこれより少なくなると子プロセスを増やす | 75 | 25 |
MaxSpareThreads |
待機スレッドがこれより多くなると子プロセスを減らす | 250 | 75 |
MaxConnectionsPerChild |
子プロセスが処理する接続数の上限(0は無制限) | 0 | 0 |
Apacheの既定値は公式マニュアル(mpm_common)の値です。Debian/Ubuntuは /etc/apache2/mods-available/mpm_event.conf に上の右端の値を書いているので、何も変えていなければこちらが使われます。
値どうしには次の関係があり、外れると起動時に自動で値が切り下げられます。
MaxRequestWorkersはServerLimit×ThreadsPerChild以下にするMaxRequestWorkersはThreadsPerChildの整数倍にするThreadsPerChildはThreadLimit以下にするMaxSpareThreadsはMinSpareThreads+ThreadsPerChild以上にする
上限の見積もり方
MaxRequestWorkers を大きくすれば多くのリクエストを同時に受け付けられますが、その分メモリを使います。メモリが足りなくなるとスワップが発生し、全体が遅くなります。次の順に見積もります。
- Apacheの子プロセス1つあたりのメモリ使用量を測る
- Apacheに割り当てられるメモリ(サーバー全体から、OS・データベース・PHP-FPMなどの分を引いた量)を決める
- 「割り当てられるメモリ ÷ 1プロセスあたりのメモリ」で子プロセス数の上限を出す
- 「子プロセス数 ×
ThreadsPerChild」をMaxRequestWorkersの候補にする
Apacheのプロセスのメモリ使用量(RSS)は、次のコマンドで合計と平均を出せます。
ps -C apache2 -o rss= | awk '{s+=$1; n++} END {printf "%d processes, %.1f MB total, %.1f MB avg\n", n, s/1024, s/1024/n}'
RHEL系ではプロセス名が httpd なので、ps -C httpd にします。RSSには共有メモリも含まれるため、合計は実際より多めに出ます。見積もりとしては安全側の値になります。アクセスの多い時間帯に測ってください。
PHP-FPMと組み合わせている場合、PHPの処理はPHP-FPMのプロセスで行われます。Apacheのスレッドを増やしても、PHPを同時に処理できる数はPHP-FPMの pm.max_children で決まります。PHPのページが遅いときは、Apacheより先にPHP-FPMの設定とメモリを確かめます。
設定の書き場所と設定例
Debian/Ubuntuでは、event MPMなら /etc/apache2/mods-available/mpm_event.conf、worker MPMなら /etc/apache2/mods-available/mpm_worker.conf を編集します。apache2.conf に書く必要はありません。
RHEL系では、/etc/httpd/conf.modules.d/00-mpm.conf で使うMPMを選び、値は /etc/httpd/conf/httpd.conf か /etc/httpd/conf.d/ の下に作った .conf ファイルに書きます。
次は、同時に800リクエストまで処理する設定の例です。ThreadsPerChild を50にし、子プロセス16個(ServerLimit 16)で800スレッドになるようにしています。
<IfModule mpm_event_module>
ServerLimit 16
StartServers 2
MinSpareThreads 50
MaxSpareThreads 150
ThreadLimit 64
ThreadsPerChild 50
MaxRequestWorkers 800
MaxConnectionsPerChild 0
</IfModule>
worker MPMの場合は、<IfModule mpm_worker_module> にして同じディレクティブを書きます。数値は例です。前の節の見積もりで出した値に合わせてください。
設定を確かめて反映する
sudo apache2ctl configtest
値どうしの関係が合っていないと、ここで警告が出ます。たとえば ServerLimit が16のまま ThreadsPerChild 25、MaxRequestWorkers 600にすると、次のように表示され、400に切り下げられます。
AH00515: WARNING: MaxRequestWorkers of 600 would require 24 servers and would exceed ServerLimit of 16, decreasing to 400. To increase, please see the ServerLimit directive.
ThreadsPerChild の整数倍になっていない場合は、次の警告が出ます。
AH00513: WARNING: MaxRequestWorkers of 410 is not an integer multiple of ThreadsPerChild of 25, decreasing to nearest multiple 400, for a maximum of 16 servers.
警告が消えて Syntax OK になったら反映します。
# MaxRequestWorkers や ThreadsPerChild などを変えた場合
sudo systemctl reload apache2
# ServerLimit または ThreadLimit を変えた場合
sudo systemctl restart apache2
ServerLimit と ThreadLimit は、Apacheを止めずに設定を読み直す方法(reload)では変更が無視されます。これらを変えたときは restart で起動し直します。restartでは処理中の接続が切れるので、アクセスの少ない時間に行います。reloadとrestartの違いはApacheの再起動とリロードの違いを参照してください。
混み具合を確かめる
server-statusで使用中のスレッド数を見る
mod_statusを有効にしていれば、server-status で使用中(BusyWorkers)と待機中(IdleWorkers)のスレッド数を見られます。Debian/Ubuntuでは標準で有効になっていて、サーバー自身からのアクセスだけが許可されています。
curl -s "http://127.0.0.1/server-status?auto" | grep -E "^(BusyWorkers|IdleWorkers|Processes)"
BusyWorkers: 1
IdleWorkers: 99
Processes: 2
アクセスの多い時間帯に BusyWorkers が MaxRequestWorkers に近づいているなら、上限が足りていない可能性があります。mod_statusの設定はmod_statusでApacheの状態を確認する方法を参照してください。
エラーログを見る
すべてのスレッドが使用中になると、エラーログに次のメッセージが出ます。
AH00484: server reached MaxRequestWorkers setting, consider raising the MaxRequestWorkers setting
sudo grep -n "MaxRequestWorkers" /var/log/apache2/error.log
このメッセージが繰り返し出ていて、メモリにまだ余裕があるなら、MaxRequestWorkers(必要なら ServerLimit も)を上げます。メモリに余裕がない場合は、上限を上げるとスワップが増えて逆効果になるので、キャッシュの導入や、遅いページ・PHPの処理の見直しを先に行います。
abで負荷をかけて確かめる
Apacheに付属するベンチマークツール ab(Debian/Ubuntuでは apache2-utils パッケージ、RHEL系では httpd-tools パッケージ)で、同時接続を増やしたときの応答を確かめられます。
ab -n 1000 -c 50 https://example.com/
-n は総リクエスト数、-c は同時接続数です。本番のサーバーに負荷をかけると利用者に影響が出るので、検証用の環境で行うか、アクセスの少ない時間に小さい値から試します。
まとめ
event/worker MPMで同時に処理できるリクエスト数は MaxRequestWorkers で決まり、ServerLimit × ThreadsPerChild 以下、かつ ThreadsPerChild の整数倍にする必要があります。値はメモリから見積もり、Debian/Ubuntuでは mpm_event.conf に書きます。apache2ctl configtest で警告が出ないことを確かめてから反映し、ServerLimit と ThreadLimit を変えたときはrestartします。反映後は server-status の BusyWorkers とエラーログのAH00484を見て、上限が足りているかを確かめます。