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 を大きくすれば多くのリクエストを同時に受け付けられますが、その分メモリを使います。メモリが足りなくなるとスワップが発生し、全体が遅くなります。次の順に見積もります。

  1. Apacheの子プロセス1つあたりのメモリ使用量を測る
  2. Apacheに割り当てられるメモリ(サーバー全体から、OS・データベース・PHP-FPMなどの分を引いた量)を決める
  3. 「割り当てられるメモリ ÷ 1プロセスあたりのメモリ」で子プロセス数の上限を出す
  4. 「子プロセス数 × 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を見て、上限が足りているかを確かめます。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲