This guide walks you through reducing the memory footprint of Apache and the rest of a LAMP stack (Linux, Apache, MySQL/MariaDB, PHP). You’ll learn how to tune Apache’s multi-processing modules, cap PHP worker memory, and adjust MySQL buffers so your server can handle more traffic without swapping to disk. No prior tuning experience is needed, but you should have root or sudo access to the server.
What You’ll Need
- Root or sudo access to your Linux server
- Apache, MySQL/MariaDB, and PHP already installed and running
- Command-line access (SSH)
- A text editor (nano, vim, or similar)
- Basic familiarity with editing config files
Step-by-Step
- Check current memory usage. Run
free -hto see total and used RAM. Then runps aux --sort=-%mem | head -20to list the top memory consumers. Note which processes (apache2, mysqld, php-fpm) are using the most. - Identify your Apache MPM. Run
apache2ctl -V | grep MPM(on Debian/Ubuntu) orhttpd -V | grep MPM(on RHEL/CentOS). You’ll see eitherprefork,worker, orevent. The MPM determines how Apache handles connections and how much memory each process uses. - Switch to the event MPM if possible. The event MPM is the most memory-efficient for most workloads, especially with PHP-FPM. On Debian/Ubuntu, run
sudo a2dismod mpm_prefork && sudo a2enmod mpm_event. On RHEL/CentOS, edit/etc/httpd/conf.modules.d/00-mpm.confand comment/uncomment the correctLoadModuleline. Restart Apache after changing. - Tune Apache’s process limits. Edit your Apache config (usually
/etc/apache2/apache2.confor/etc/httpd/conf/httpd.conf). Look for the<IfModule mpm_*_module>block. SetMaxRequestWorkersto a value that fits your RAM. A safe starting point: divide your available RAM (in MB) by the average memory per Apache process (check withps aux | grep apache). For example, if you have 2GB RAM and each process uses 30MB, setMaxRequestWorkersto around 50. Also setMinSpareThreadsandMaxSpareThreadsto low values (e.g., 5 and 10) to avoid idle processes. - Switch PHP to PHP-FPM. PHP as an Apache module (mod_php) is memory-hungry because it runs inside every Apache process. PHP-FPM runs PHP separately and is more efficient. Install php-fpm, then disable mod_php:
sudo a2dismod php7.4(adjust version) and enable the proxy modules:sudo a2enmod proxy_fcgi setenvif. Then configure Apache to pass PHP requests to PHP-FPM. On Debian/Ubuntu, you can usesudo a2enconf php7.4-fpm. Restart Apache and PHP-FPM. - Limit PHP-FPM memory. Edit
/etc/php/7.4/fpm/pool.d/www.conf(or similar). Setpm = dynamic,pm.max_childrento a number that fits your RAM (e.g., 20),pm.start_serversto 5,pm.min_spare_serversto 5, andpm.max_spare_serversto 10. Also setphp_admin_value[memory_limit] = 128M(or lower if your app works with less). Restart PHP-FPM. - Optimize MySQL/MariaDB memory. Edit
/etc/mysql/my.cnfor/etc/my.cnf. The most important settings arekey_buffer_size(for MyISAM, set to 16-32MB),innodb_buffer_pool_size(for InnoDB, set to about 25% of your RAM, e.g., 512MB for 2GB RAM), andquery_cache_size(set to 0 or a small value like 16MB; the query cache is deprecated in MySQL 8). Also setmax_connectionsto a reasonable number (e.g., 50). Restart MySQL. - Monitor and adjust. After each change, restart services and run
free -hagain. Watch for swap usage (swapon --show). If swap is used, reduce your limits further. Usetoporhtopto see if any process is consuming too much. - Consider using a lightweight alternative for static files. If you serve a lot of static content (images, CSS, JS), offloading it to a lightweight server like Nginx or Varnish can free up Apache memory. This is more advanced but very effective.
Common Mistakes
- Setting MaxRequestWorkers too high. This is the most common mistake. If you set it too high, Apache will spawn more processes than your RAM can handle, causing swapping and a slow server.
- Keeping mod_php when using PHP-FPM. If you don’t disable mod_php, Apache will still load PHP into every process, negating the memory savings.
- Setting innodb_buffer_pool_size too large. This buffer is allocated at startup. If you set it to 80% of RAM, MySQL will use most of your memory, leaving little for Apache and PHP.
- Ignoring swap usage. If you see swap being used, your server is memory-constrained. Reduce limits immediately.
- Not restarting services after config changes. Changes only take effect after a restart.
Tips
- Use a tool like
ps_memto get accurate per-process memory usage. Install it withsudo apt install ps_memorsudo yum install ps_memand runsudo ps_memto see a clean summary. - Start with low values and gradually increase. It’s easier to add more capacity than to fix a server that’s swapping.
- Consider using a CDN for static files. This reduces the load on your server entirely.
- Use
systemctl statusto verify services are running after restarts. - Keep a backup of your config files before editing.
Troubleshooting
Apache won’t start after changing MPM. Check the error log (/var/log/apache2/error.log or /var/log/httpd/error_log). You may need to re-enable mod_php if you’re using PHP-FPM incorrectly. Ensure the proxy_fcgi module is enabled.
PHP scripts download instead of executing. This usually means the proxy_fcgi configuration is wrong. Check that your virtual host has the correct SetHandler directive, e.g., SetHandler "proxy:unix:/run/php/php7.4-fpm.sock|fcgi://localhost".
MySQL fails to start after changing buffer sizes. Check the MySQL error log (/var/log/mysql/error.log). The buffer size may be too large for your system’s shared memory. Reduce it and try again.
Server still swaps. Use ps aux --sort=-%mem to find the culprit. It might be another service, not Apache. Consider adding swap space (sudo fallocate -l 2G /swapfile) as a temporary measure, but the goal is to reduce memory usage.
Apache is slow after reducing MaxRequestWorkers. If you set it too low, requests will queue up. Check apache2ctl status to see if there are many waiting requests. Increase the value slightly, but watch memory.
Frequently Asked Questions
Q: What is the best MPM for Apache? The event MPM is generally the best for performance and memory, especially with PHP-FPM. Prefork is only needed for older PHP modules that are not thread-safe.
Q: How much memory should I allocate to MySQL? A common rule of thumb is 25% of available RAM for InnoDB buffer pool. But this depends on your data size and workload. Start low and monitor.
Q: Is PHP-FPM always better than mod_php? Yes, for memory usage, PHP-FPM is almost always better because it separates PHP processes from Apache, allowing Apache to be more efficient. The only exception is if you have a very simple server with minimal traffic.
Q: What is the difference between MaxRequestWorkers and MaxClients? They are the same thing in Apache 2.4. In older versions, MaxClients was used. The directive was renamed to MaxRequestWorkers.
Q: Can I use Nginx instead of Apache? Yes, Nginx is more memory-efficient for static files and can also handle PHP via PHP-FPM. But switching is a bigger change. You can also run Nginx as a reverse proxy in front of Apache to offload static content.
Q: How do I know if my server is swapping? Run swapon --show to see if swap is in use. Also free -h will show swap usage. If the ‘used’ column is high, you may be swapping.
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.
More cards in this drawer
- Motorola Phone Recovery: How to Recover Data
- Poco X3 GT Dimensity 1100 67W Fast Charging Launched?5.00 min/km
- Flash Converter: What It Is & How to Use It
- Choosing a Pipe Flow Meter for Swirling Flow
- Convert 2D Videos to Oculus Rift VR: How-To
- DRAM Light on Motherboard: Meaning & Fixes5.00 min/km