A SAPI (Server API) connects the engine to whatever started it: a terminal, an HTTP request or a FastCGI message. Each SAPI reads its own php.ini. This script reports where it runs:
<?php
header('Content-Type: text/plain');
printf("%-14s %-28s %-8s pid=%d memory=%s time=%ss\n",
PHP_SAPI, php_ini_loaded_file(), posix_getpwuid(posix_geteuid())['name'],
getmypid(), ini_get('memory_limit'), ini_get('max_execution_time'));Here it is run four ways: from the terminal, through the built-in server (php -S 127.0.0.1:8201), through Apache 129 passing .php files to PHP-FPM via proxy_fcgi, and through Apache with mod_php:
$ php sapi.php cli /etc/php/8.5/cli/php.ini dev pid=35784 memory=-1 time=0s $ curl http://127.0.0.1:8201/sapi.php cli-server /etc/php/8.5/cli/php.ini dev pid=35785 memory=-1 time=30s $ curl http://localhost/sapi.php # Apache event MPM + PHP-FPM fpm-fcgi /etc/php/8.5/fpm/php.ini www-data pid=18566 memory=128M time=30s $ curl http://localhost/sapi.php # Apache prefork MPM + mod_php apache2handler /etc/php/8.5/apache2/php.ini www-data pid=35980 memory=128M time=30s
The CLI has no memory limit on Ubuntu 225 and no time limit at all: the CLI SAPI forces max_execution_time to 0 whatever php.ini says. Under FPM the PID is a php-fpm: pool www worker, separate from Apache; under mod_php it is an Apache child, because the interpreter lives inside it.
| SAPI | PHP_SAPI | Runs as | Use it for |
|---|---|---|---|
| CLI | cli | Your login user | Scripts, cron, Composer 5,243 |
| Built-in server | cli-server | Your login user | Local development only |
| PHP-FPM | fpm-fcgi | The pool's user | Production |
| Apache module | apache2handler | Apache's user | Legacy; needs prefork |
PHP-FPM is the production default. A master process manages pools of workers, each with its own user and limits, leaving Apache free to use its threaded event MPM. Ubuntu builds PHP non-thread-safe (the NTS in php -v), so mod_php forces prefork, one process per connection. PHP-FPM via proxy_fcgi wires Apache to FPM; Performance and OPcache tunes the pool. The built-in server is one process that stalls while any request blocks (PHP_CLI_SERVER_WORKERS=4 forks workers on Linux), and the manual says it must never face a public network: bind it to 127.0.0.1.