PHP LSAPI suEXEC ProcessGroup

PHP LSAPI 6.4 introduced the new suEXEC ProcessGroup mode. ProcessGroup allows shared hosting providers with extra memory to get better PHP performance through per-user opcode caching. It also allows custom php.ini files, and thus CloudLinux’s PHP Selector.

What is suEXEC?

suEXEC makes PHP more secure by running each PHP process as the owner of a particular account and not as the web server user. This means that even if one user on a server is compromised, PHP scripts run from their account will not have access to other users' files. suEXEC has long been a basic feature of shared hosting.

What is suEXEC ProcessGroup?

suEXEC ProcessGroup is set up similarly to PHP-FPM pools. ProcessGroup provisions a parent process for each ProcessGroup user. This parent process runs as the owner of the user’s document root and spawns new child processes when that user needs a PHP process. Forking child processes this way requires less overhead than creating brand new processes and these processes can share an opcode cache. ProcessGroup thus maintains the security of suEXEC, but spawns processes faster and allows for extremely effective per-user opcode caches.

Benefits


Faster process generation

Forking child processes is faster than creating new processes because it has less overhead.

LiteSpeed's most powerful suEXEC opcode caching

ProcessGroup allows for LiteSpeed's most powerful suEXEC opcode caching. Opcode cache stores compiled PHP scripts and variables, allowing for faster PHP response. But opcode cache memory can only be shared among child processes forked off the same parent process and it is flushed if the parent process ends. In suEXEC Worker (LiteSpeed's default suEXEC mode), all processes are standalone and opcode cache memory is flushed every time a PHP process ends. Because, in ProcessGroup, child processes are forked off a continuous parent process, each user's cache is not flushed and their scripts can be used many times. (See vs. suEXEC Daemon mode section for why this is more effective than Daemon mode opcode caching.)

Custom php.ini files

Because each process group has its own parent process, this means PHP suEXEC ProcessGroup is compatible with custom php.ini files. A custom php.ini allows the use of CloudLinux’s PHP Selector.

Can be set at the server or vhost level

ProcessGroup is set through a directive in your httpd.conf files at either the server or virtual host level. (See the Configuration section.) Putting this directive at the virtual host level allows you to decide which users get a personal opcode cache.

Comparison to other setups


Apache/nginx setups

vs. suPHP

suPHP is the standard suEXEC setup for Apache.

  • All LSWS suEXEC modes (Worker, Daemon, and ProcessGroup) are far faster than suPHP because suPHP uses CGI. CGI is much, much slower than LiteSpeed's LSAPI.
  • suPHP creates a new standalone process for each PHP process. As explained above, creating these new processes requires overhead, is time-consuming, and prevents the effective use of opcode cache.
vs. PHP-FPM pools

PHP-FPM was created for Apache and other web servers to make use of FastCGI with PHP.

  • FastCGI is a speedier than CGI, but, our benchmarks show, LSAPI is still about 20% faster than FCGI.
  • To get security similar to suEXEC from PHP-FPM, you have to manually set up pools of processes for each user. ProcessGroup can be automatically set up for the whole server by adding the ProcessGroup directive in the server-level httpd.conf file.
  • PHP-FPM's pools always leave at least one process in each pool running, meaning wasted system resources even when a particular site is not being used. This is especially a problem for servers with many users and thus many pools. The ProcessGroup parent process, however, will be killed when it has been idle for too long.

Other LiteSpeed setups

vs. suEXEC daemon mode

LiteSpeed's suEXEC daemon mode forks all processes from one constantly running daemon process.

  • Because suEXEC Daemon mode forks all processes off one parent process, everyone on that server shares one large opcode cache. If there are many users, this opcode cache can fill up and each user’s scripts may get bumped off the cache before they’re accessed very much. By allowing per-user opcode caches, ProcessGroup allows for more effective opcode caching — each user's scripts stay in the cache to be accessed many times irrespective of what other users do.
  • Daemon mode does not allow custom php.ini files. ProcessGroup does, which also allows for the use of CloudLinux's PHP Selector.
  • ProcessGroup can require more resources than suEXEC Daemon mode: Each ProcessGroup must have its own parent process in addition to other processes. Giving each user a per-user opcode cache should mean more memory for opcode caching than having everyone share one opcode cache.
  • ProcessGroup can be used in conjunction with Daemon mode by setting up Daemon mode at the server level and enabling ProcessGroup on certain virtual hosts that require more powerful opcode caching.
See our comparison of suEXEC setups for more information

Limitations


ProcessGroup keeps one parent process running in addition to all their child processes. This creates a lot of extra processes that you wouldn’t have in LiteSpeed’s suEXEC Worker or Daemon mode. (This can be controlled to some degree with the Max Idle Time setting described below. This causes LSWS to kill ProcessGroup parent processes when they’ve been idle for a certain amount of time.)

Personal opcode caches must be reasonably large in order to be of any use. This almost certainly means setting aside more RAM for opcode caching than you would with suEXEC Daemon mode. ProcessGroup is thus meant for hosts that are willing to use extra memory to see performance enhancements. You must be careful, though. If you portion out too much memory for per-user opcode caches, you could run out of memory.

Configuration


Prerequisites

  • Auto Start (WebAdmin console > Configuration > External App > your external application) must be set to "Yes" or "Through CGI Daemon". Setting Auto Start to "Through CGI Daemon" may save resources by not starting parent processes for idle process groups at startup.
  • If you wish to use suEXEC Daemon mode for some users while using ProcessGroup for others, change Run On Start Up (WebAdmin console > Configuration > External App > your external application) to "suEXEC Daemon". If Run On Start Up is set to "suEXEC Daemon", ProcessGroup will override Daemon mode wherever ProcessGroup is enabled.
  • If Run On Start Up (WebAdmin console > Configuration > External App > your external application) is set to "No", LSWS will start a parent process for each process group only when traffic is coming in to that user. This is recommended. Setting Run On Start Up to "Yes" may result in errors.

Enabling ProcessGroup

ProcessGroup is enabled by placing the directive LSPHP_ProcessGroup in an httpd.conf file. This can be done at the server or virtual host level. If done at the server level, all virtual hosts will use ProcessGroup. If done at the virtual host level, only that virtual host will use ProcessGroup.

Example configuration:

<IfModule LiteSpeed>
LSPHP_ProcessGroup on
LSPHP_Workers 15
</IfModule>
Note the <IfModule LiteSpeed> . The two directives, LSPHP_ProcessGroup and LSPHP_Workers, are LiteSpeed-specific directives. Apache will not understand them and may crash if they are not protected.

Additional configurations

  • LSPHP_Workers sets the maximum number of child processes that the parent process can spawn. It is optional. If set, it will override the PHP suEXEC Max Conn setting (WebAdmin console > Configuration > Server > General > Using Apache Configuration File).
  • Per-user opcode cache size is set in your php.ini file. How to set this depends on what opcode cache you’re using.
  • The Max Idle Time setting (WebAdmin console > Configuration > External App > your external application) will control how long before idle parent processes are killed.

Special notes for use with cPanel

  • The ProcessGroup directive should be put in an include file, otherwise it will be overwritten when you upgrade WHM.
  • When configuring ProcessGroup at the server level, the directive should be placed in /usr/local/apache/conf/includes/pre_virtualhost_global.conf
  • When configuring ProcessGroup at the virtual host level, the directive should be placed in a virtual host-level include file.
  • Guides for adding include files can be found on this page from cPanel's site.

STAY CONNECTED