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 -von Debian/Ubuntu,httpd -von AlmaLinux/Rocky). - A copy of the config tree, so a bad switch is one command away from being undone:
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.
apache2ctl -V | grep -i "server mpm"Expected output on a working event setup:
Server MPM: eventThe same on AlmaLinux or Rocky:
httpd -V | grep -i "server mpm"Then confirm which MPM module files are actually loaded:
apache2ctl -M | grep mpmYou 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
- Disable the old MPM and the mod_php handler:
sudo a2dismod mpm_prefork
sudo a2dismod php8.3Replace php8.3 with the version you actually have; ls /etc/apache2/mods-enabled | grep php lists it.
- Enable the new MPM:
sudo a2enmod mpm_eventThe 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.
- Test the configuration before touching the running service:
sudo apache2ctl configtestExpect Syntax OK. Anything else, fix it now — a restart with a broken config stops the site.
- Restart:
sudo systemctl restart apache2Switch 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:
# 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.soThen validate and restart:
sudo apachectl configtest
sudo systemctl restart httpdBefore you do this, grep for stray MPM directives added by panels or leftover packages:
sudo grep -rn "mpm_" /etc/httpd/conf.modules.d/ /etc/httpd/conf.d/ | grep LoadModuleEvery 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:
apache2ctl -V | grep -i "server mpm"Confirm the site answers:
curl -sI http://203.0.113.10/ | head -n 1A 200 or a 301 line means the vhost still serves. Now prove PHP is still running — create a temporary file in the docroot:
<?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:
sudo tail -n 30 /var/log/apache2/error.logOn 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 activeLoadModule mpm_*lines. Run thegrepabove, comment out all but one, thenapachectl configtestagain. The service will not start until this is clean.- PHP pages return 500, or the browser downloads a
.phpfile → mod_php is still enabled while event or worker is loaded. Disable the PHP module (sudo a2dismod php8.3), installphp-fpm, and wire it up withproxy_fcgias in the PHP-FPM guide. a2dismod mpm_preforksucceeds but-Vstill shows prefork → the MPM is compiled statically, or a symlink in/etc/apache2/mods-enabledsurvived. Checkapache2ctl -landls -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
- Run PHP-FPM with Apache using proxy_fcgi and mpm_event to finish the migration properly.
- Tune Apache MPM settings to stop memory exhaustion once event is live.
- How to find and read Apache access and error logs for faster diagnosis next time.
- Fix Apache failed to start if a config change locks you out of a restart.
