2026年5月17日

2026年5月17日

Apacheの同時接続数の上限を設定する方法|MaxRequestWorkers・ServerLimit・ListenBacklog

Apacheが同時に処理できる接続の数は、MPM(マルチプロセッシングモジュール)の設定で決まります。中心になるのは MaxRequestWorkers で、これを超えた接続は待ち行列に入ります。上限が小さすぎるとアクセスが集中したときに待たされ、大きすぎるとメモリーが足りなくなってサーバー全体が不安定になります。

この記事では、Apache 2.4で同時接続数の上限を決める設定と、値の決め方、上限に達しているかの確認方法を説明します。設定値の既定値は、2026年10月時点のApache 2.4の公式ドキュメントに基づきます。

まずMPMを確認する

同じ指令でも、MPMによって意味や既定値が変わります。最初に、どのMPMで動いているかを確認します。

# Debian/Ubuntu
sudo apachectl -V | grep -i mpm

# RHEL系(AlmaLinux・Rocky Linuxなど)
sudo httpd -V | grep -i mpm
MPM 処理の単位 特徴
event プロセス+スレッド KeepAliveで待っている接続をスレッドから切り離して扱える。2026年10月時点の主要ディストリビューションの既定
worker プロセス+スレッド 1スレッドが1接続を受け持つ
prefork プロセスのみ 1プロセスが1接続を受け持つ。スレッドに対応しないモジュール(mod_phpなど)と組み合わせるときに使う

MPMの違いと選び方はApacheのWorker/Prefork/Eventの違いと選び方で扱っています。

同時接続数に関わる設定

設定 意味 既定値
MaxRequestWorkers 同時に処理するリクエストの上限。超えた接続は待ち行列に入る(Apache 2.3.13より前の名前は MaxClients) prefork:256、event・worker:400(ServerLimit 16 × ThreadsPerChild 25)
ServerLimit 子プロセス数の上限。preforkでは MaxRequestWorkers に設定できる値の上限になる preforkは256、event・workerは16
ThreadsPerChild 子プロセス1つが作るスレッドの数(event・worker) 25
ThreadLimit ThreadsPerChild に設定できる値の上限(event・worker) 64
ListenBacklog 処理を待つ接続の待ち行列の長さ 511
MaxConnectionsPerChild 子プロセス1つが生涯に処理する接続の数。超えるとそのプロセスは終了し、作り直される(旧名 MaxRequestsPerChild) 0(終了しない)

注意したいのは MaxConnectionsPerChild です。名前から「プロセスごとの同時接続数の上限」と誤解されがちですが、同時接続数とは関係ありません。プロセスを定期的に作り直すための設定で、モジュールやPHPのメモリーリークでプロセスのメモリーが増え続ける場合に、0以外の値を設定します。

また、Listen 80 は待ち受けるポートを指定するだけで、接続数を制限する働きはありません。

設定ファイルの場所

ディストリビューション MPMの選択 MPMの設定を書く場所
Debian/Ubuntu a2enmod / a2dismod(mpm_event など) /etc/apache2/mods-available/mpm_event.conf(preforkなら mpm_prefork.conf)
RHEL系 /etc/httpd/conf.modules.d/00-mpm.conf の LoadModule 行 /etc/httpd/conf.d/mpm.conf などを作成して記述

RHEL系の /etc/httpd/conf.d/ にある .conf ファイルは、httpd.conf から読み込まれます。

event・workerでの設定例

event・workerでは、同時に処理できる数はスレッドの総数で決まります。値は次の関係を満たすように決めます。

  • MaxRequestWorkers ÷ ThreadsPerChild = 子プロセスの数。この数が ServerLimit を超えてはいけない
  • MaxRequestWorkers は ThreadsPerChild の倍数にする(倍数でないと、起動時に切り下げられ、警告が出る)
  • ThreadsPerChild は ThreadLimit を超えてはいけない

既定の ServerLimit 16、ThreadsPerChild 25では、上限は400です。800まで上げたい場合は、子プロセスが32個必要になるので、ServerLimit も32に上げます。

<IfModule mpm_event_module>
    StartServers             2
    ServerLimit              32
    ThreadLimit              64
    ThreadsPerChild          25
    MaxRequestWorkers        800
    MinSpareThreads          25
    MaxSpareThreads          75
    MaxConnectionsPerChild   0
</IfModule>

Debian/Ubuntuのパッケージに含まれる mpm_event.conf では、MaxRequestWorkers が150になっています(ServerLimit の記述はなく、既定の16が使われます)。

preforkでの設定例と、メモリーからの目安

preforkでは、1つの接続を1つのプロセスが処理するため、同時接続数はプロセスの数そのものです。mod_phpを使っている場合、1プロセスが数十MBのメモリーを使うことも珍しくありません。上限は、メモリーの量から逆算して決めます。

# Apacheのプロセス1つあたりの平均メモリー使用量(MB)。RHEL系は apache2 を httpd に
ps -C apache2 -o rss= | awk '{sum+=$1; n++} END {if (n) printf "%d processes, avg %.1f MB\n", n, sum/n/1024}'

# サーバー全体のメモリー
free -m

たとえば、Apacheに使わせてよいメモリーが2GB(データベースやOSの分を除いた量)、1プロセスの平均が50MBなら、2048 ÷ 50 ≒ 40 が目安です。アクセスが多い時間帯に測った値を使ってください。

<IfModule mpm_prefork_module>
    StartServers             5
    MinSpareServers          5
    MaxSpareServers         10
    MaxRequestWorkers       40
    MaxConnectionsPerChild   0
</IfModule>

preforkで MaxRequestWorkers を256より大きくする場合は、ServerLimit も同じ値以上に上げます。

ListenBacklogとOSの上限

MaxRequestWorkers に達した後の接続は、OSの待ち行列に入り、空きが出るのを待ちます。この待ち行列の長さが ListenBacklog です。ただし、OS側にも上限があり、Linuxでは net.core.somaxconn の値より大きくはなりません。

sysctl net.core.somaxconn

待ち行列を長くしても、処理できる数が増えるわけではありません。待たされた接続はいずれタイムアウトします。待ち行列を延ばすより、MaxRequestWorkers と処理の速さを見直すほうが先です。

KeepAliveとの関係

KeepAliveが有効だと、1つの接続が次のリクエストを待つ間(KeepAliveTimeout、既定5秒)も接続が保たれます。preforkとworkerでは、この待ち時間もプロセスやスレッドを1つ占有するため、上限に達しやすくなります。eventでは、待っている接続をスレッドから切り離して扱うため、この影響を受けにくくなります。詳しくはApacheのKeepAlive設定で接続を最適化するを参照してください。

PHP-FPMとの釣り合い

Apacheから PHP-FPM にPHPの処理を渡している構成(event+mod_proxy_fcgi)では、PHPを同時に実行できる数はApacheではなくPHP-FPMのプール設定 pm.max_children で決まります。php_value max_children のようにApacheの設定ファイルに書いても効きません(php_value はmod_php用の書き方で、max_children というPHPの設定項目もありません)。

PHP-FPMのプール設定ファイル(2026年10月時点のDebian/UbuntuのPHP 8.3なら /etc/php/8.3/fpm/pool.d/www.conf、RHEL系なら /etc/php-fpm.d/www.conf)で設定します。

pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6
sudo systemctl reload php8.3-fpm   # RHEL系は php-fpm

Apacheの MaxRequestWorkers が pm.max_children よりずっと大きいと、Apacheは接続を受け付けても、PHPの処理はPHP-FPMの空きを待つことになります。PHP-FPMのログに「server reached pm.max_children setting」という警告が出ていれば、PHP側が上限に達しています。pm.max_children も、PHP-FPMのプロセス1つあたりのメモリーから逆算して決めてください。PHP-FPMとの連携はApacheでPHP-FPMと連携する方法で扱っています。

設定を反映する

# 構文の確認
sudo apachectl configtest

# 反映(Debian/Ubuntu。RHEL系は httpd)
sudo systemctl restart apache2

ServerLimit と ThreadLimit は、graceful(systemctl reload)による再読み込みでは変更されません。これらを変えたときは、systemctl restart で停止と起動を行ってください。

上限に達しているかを確認する

エラーログ

MaxRequestWorkers に達すると、Apacheのエラーログに次のような記録が出ます(eventではAH00484、preforkではAH00161)。

server reached MaxRequestWorkers setting, consider raising the MaxRequestWorkers setting
# Debian/Ubuntu。RHEL系は /var/log/httpd/error_log
sudo grep -i "MaxRequestWorkers" /var/log/apache2/error.log

mod_status

mod_statusを有効にすると、処理中のワーカー数(BusyWorkers)と空いているワーカー数(IdleWorkers)を確認できます。/server-status は自分のサーバーからだけ見られるように制限しておきます。

<Location "/server-status">
    SetHandler server-status
    Require local
</Location>
curl -s "http://localhost/server-status?auto" | grep -E "BusyWorkers|IdleWorkers"

アクセスの多い時間帯に BusyWorkers が MaxRequestWorkers に張り付いていれば、上限が足りていません。メモリーに余裕があれば上限を上げ、余裕がなければ、キャッシュの導入や処理の重いページの改善で1リクエストの処理時間を短くします。mod_statusの読み方はApacheのmod_statusでサーバー状態を確認するで扱っています。

IPアドレスごとに接続数を制限したい場合

ここまでの設定は、サーバー全体の上限です。特定のIPアドレスからの大量の接続を抑えたい場合、Apache 2.4の標準モジュールには、IPアドレスごとの同時接続数を制限する指令はありません。サードパーティのモジュールを使います。

まとめ

  • 同時に処理できる数の上限は MaxRequestWorkers。event・workerでは ServerLimit × ThreadsPerChild の範囲で決まる
  • preforkでは、プロセス1つのメモリー使用量から上限を逆算する
  • MaxConnectionsPerChild(旧 MaxRequestsPerChild)はプロセスを作り直すまでの接続数で、同時接続数の上限ではない
  • ListenBacklog は待ち行列の長さで、OSの net.core.somaxconn を超えない。処理できる数は増えない
  • PHP-FPMを使う場合、PHPの同時実行数は pm.max_children で決まる。php_value では設定できない
  • ServerLimit・ThreadLimit を変えたら restart で反映し、エラーログとmod_statusで上限に達していないかを確認する

お気軽にご相談ください

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