Control panels

Troubleshooting Apache MPM switching: worker vs event vs prefork

Apache loads only one MPM at a time, and switching between prefork, worker and event fails when mod_php, duplicate LoadModule lines or panel rules get in the way. This guide shows how to check, switch and fix it.

AdvancedLinux server7 min read

Apache loads exactly one Multi-Processing Module at a time, and that choice decides how every request is handled: prefork forks a process per connection, worker uses threads inside fewer processes, and event adds an async listener on top of worker. Switching Apache MPM between them is the usual fix for memory exhaustion or slow concurrent traffic — and it is also where you get AH00534: More than one MPM loaded, blank PHP pages, or a server that refuses to restart. This guide walks through identifying the running MPM, checking what depends on prefork, switching cleanly on Debian/Ubuntu and on AlmaLinux/Rocky, and fixing the failures that follow.

Before you start

You need:

  • Root or sudo access to the Linux VPS, and SSH or the browser console from your VPS provider's control panel.
  • Knowledge of which distribution and Apache version you run (apache2 -v on Debian/Ubuntu, httpd -v on AlmaLinux/Rocky).
  • A copy of the config tree, so a bad switch is one command away from being undone:
Bash
sudo cp -a /etc/apache2 /root/apache2-backup-$(date +%F)

On RHEL-family systems use sudo cp -a /etc/httpd /root/httpd-backup-$(date +%F).

Warning: Restarting Apache drops every open connection for a second or two. If the site is live, restart during a quiet window, not mid-checkout.

Note: If the server is managed by cPanel/WHM, do not hand-edit MPM files. EasyApache 4 owns them and will overwrite your change on the next rebuild. Use WHM instead, as covered below.

Identify the running MPM

Ask Apache directly rather than guessing from the package list.

Bash
apache2ctl -V | grep -i "server mpm"

Expected output on a working event setup:

Server MPM:     event

The same on AlmaLinux or Rocky:

Bash
httpd -V | grep -i "server mpm"

Then confirm which MPM module files are actually loaded:

Bash
apache2ctl -M | grep mpm

You should see exactly one mpm_*_module (shared) line. Two lines, or a line plus a static entry, is the classic duplicate-load failure.

One more check is worth knowing: apache2ctl -l (or httpd -l) lists modules compiled into the binary. If you see mpm_event.c or prefork.c there, that MPM is static and cannot be changed with a2dismod — you would need a rebuilt package.

Check what depends on prefork

Before switching, find out what will break:

  • mod_php (libapache2-mod-php) is not thread-safe and only works with prefork. Switching to event or worker while it is loaded produces 500 errors or serves raw PHP source.
  • mod_ruid2 and mod_itk are prefork-only. Hosting setups that use them per-user must stay on prefork.
  • Third-party modules written against the pre-fork API can compile but crash children under threads. Check the vendor's docs if you are unsure.
  • PHP-FPM is the supported replacement: once PHP runs as a separate service, Apache can use event or worker safely.

To go the FPM route, follow running PHP-FPM with Apache using proxy_fcgi and mpm_event. For a broader look at server choices, see Nginx vs Apache vs OpenLiteSpeed.

Warning: On Debian/Ubuntu, disabling mpm_prefork while php*.conf is still enabled will take PHP offline on every vhost. Disable the PHP module in the same maintenance window.

Switch to event on Debian or Ubuntu

  1. Disable the old MPM and the mod_php handler:
Bash
sudo a2dismod mpm_prefork
sudo a2dismod php8.3

Replace php8.3 with the version you actually have; ls /etc/apache2/mods-enabled | grep php lists it.

  1. Enable the new MPM:
Bash
sudo a2enmod mpm_event

The script prints a conflict notice ("Considering conflict mpm_prefork for mpm_event") and enables the module anyway. If it reports Module mpm_event already enabled, skip to the troubleshooting section.

  1. Test the configuration before touching the running service:
Bash
sudo apache2ctl configtest

Expect Syntax OK. Anything else, fix it now — a restart with a broken config stops the site.

  1. Restart:
Bash
sudo systemctl restart apache2

Switch to event on AlmaLinux or Rocky

RHEL-family builds ship an MPM config fragment rather than the Debian symlink system. Edit /etc/httpd/conf.modules.d/00-mpm.conf so exactly one LoadModule line is active:

Apache
# LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
# LoadModule mpm_worker_module modules/mod_mpm_worker.so
LoadModule mpm_event_module modules/mod_mpm_event.so

Then validate and restart:

Bash
sudo apachectl configtest
sudo systemctl restart httpd

Before you do this, grep for stray MPM directives added by panels or leftover packages:

Bash
sudo grep -rn "mpm_" /etc/httpd/conf.modules.d/ /etc/httpd/conf.d/ | grep LoadModule

Every hit except the one you want must be commented out. On RHEL 8 and later, mod_php is gone and PHP is expected to run through PHP-FPM, so this switch is usually straightforward.

Tip: A common cause of AH00534 is a second file such as 00-mpm.conf.rpmnew or a panel-generated snippet loading another MPM. Comment the duplicate; do not delete the package file.

Tune the pool after switching

Event and worker size themselves with threads per child, not processes, so the old prefork numbers are wrong. Review MaxRequestWorkers, ThreadsPerChild and ServerLimit in your MPM config before you put traffic back on the box. The step-by-step numbers are in tuning Apache MPM settings to stop memory exhaustion.

Check it works

Confirm the MPM is active:

Bash
apache2ctl -V | grep -i "server mpm"

Confirm the site answers:

Bash
curl -sI http://203.0.113.10/ | head -n 1

A 200 or a 301 line means the vhost still serves. Now prove PHP is still running — create a temporary file in the docroot:

PHP
<?php echo PHP_SAPI;

Request it with curl -s http://203.0.113.10/check.php and you should see fpm-fcgi, not a wall of PHP source. Delete the file straight after.

Finally, read the log for child process failures:

Bash
sudo tail -n 30 /var/log/apache2/error.log

On AlmaLinux/Rocky the path is /var/log/httpd/error_log. A clean restart shows resuming normal operations with no segfault lines.

Troubleshooting

  • AH00534: httpd: Configuration error: More than one MPM loaded → two active LoadModule mpm_* lines. Run the grep above, comment out all but one, then apachectl configtest again. The service will not start until this is clean.
  • PHP pages return 500, or the browser downloads a .php file → mod_php is still enabled while event or worker is loaded. Disable the PHP module (sudo a2dismod php8.3), install php-fpm, and wire it up with proxy_fcgi as in the PHP-FPM guide.
  • a2dismod mpm_prefork succeeds but -V still shows prefork → the MPM is compiled statically, or a symlink in /etc/apache2/mods-enabled survived. Check apache2ctl -l and ls -l /etc/apache2/mods-enabled | grep mpm.
  • Apache starts but child processes die: child pid... exit signal Segmentation fault (11) → a non-thread-safe module is loaded under worker or event. Comment out mod_ruid2, mod_itk and any legacy module one at a time, restarting between changes, until the crashes stop.
  • Your change vanishes after an EasyApache rebuild in cPanel/WHM → the MPM is set in the WHM profile, not in the files. Switch it in WHM as described in switching Apache MPM to event in cPanel and tuning Apache settings in WHM Global Configuration.
  • Site loads but some vhosts 403 → the switch did not cause it directly, but the docroot permissions may need review. See fixing 403 Forbidden in Apache and Linux file system permissions: ACL vs standard permissions.

Next steps

Was this guide helpful?

Still stuck?

Ask MdmHost AI for a quick answer, or open a ticket and our team will take a look. We are here 24/7.