My host offers PHP as 'Apache module', 'FastCGI' and 'PHP-FPM'. Nginx tutorials mention php-fpm and .htaccess php_value lines break on my host with a 500 error. How do these differ?
DEV3 Developer Forum
What is the difference between mod_php, PHP-FPM and CGI, and which should I use?
Every post is reviewed first. Usually reviewed within 24 hours.
1 reply
They are different ways for the web server to run PHP code.
mod_php (Apache module)
PHP is embedded in every Apache worker process. Simple and supports php_value / php_flag in .htaccess. Requires Apache's prefork MPM, uses more memory (each worker carries PHP even for static files), and all sites on the server run as the same user unless extra isolation is used. Mostly legacy.
CGI / FastCGI (suPHP, LSAPI and similar)
The server launches PHP processes per user. Good isolation on shared hosting. PHP settings go in php.ini or .user.ini, not in .htaccess php_value lines, which cause the 500 error you saw.
PHP-FPM (FastCGI Process Manager)
A separate service with pools of PHP workers. Apache (via proxy_fcgi) or Nginx forward .php requests to it. This is the standard modern setup because:
- the web server stays lightweight and serves static files itself;
- pools can run per site and per user with their own limits;
- you can tune workers (
pm = dynamic,pm.max_children); - OPcache is shared across workers and reloads gracefully (
systemctl reload php8.3-fpm).
Nginx snippet:
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
Also add try_files $uri =404; so crafted paths cannot reach PHP.
Which settings go where
| Setup | Where to set upload_max_filesize etc. |
|---|---|
| mod_php | php.ini or .htaccess (php_value) |
| FPM / CGI | php.ini, .user.ini, pool php_admin_value, cPanel INI editor |
Sizing PHP-FPM: pm.max_children roughly equals free RAM divided by the average PHP process size (often 40 to 120 MB for a framework app). Too high means swapping and OOM kills; too low means 502/504 errors under load.
Recommendation: PHP-FPM with Nginx or Apache for anything new; enable OPcache in production (opcache.enable=1, opcache.validate_timestamps=0 with deploy-time reloads, if you can reload).
See the nginx config generator for a complete server block.