CresignSys Learn — Lesson 044

Written by

in

PHP-FPM From the Absolute Basics

We now have:

Browser
   ↓
DNS
   ↓
IP
   ↓
TCP
   ↓
TLS
   ↓
HTTP
   ↓
Nginx
   ↓
?

The missing component is:

PHP-FPM

This is one of the most important technologies to understand if you want to build and manage WordPress hosting.


1. First: What Is PHP?

PHP is a programming language commonly used for server-side web applications.

WordPress is primarily written in PHP.

For example:

<?php
echo "Hello World";

A PHP program runs on the server.

The browser normally does not receive the PHP source code.

Instead:

PHP source
   ↓
PHP interpreter
   ↓
Generated result
   ↓
HTML
   ↓
Browser

2. PHP Is Server-Side

Compare:

HTML

<h1>Hello</h1>

The browser receives and interprets the HTML.

PHP

<?php
echo "<h1>Hello</h1>";

The server executes the PHP first.

The browser receives the resulting HTML:

<h1>Hello</h1>

3. Simple Example

Suppose the server contains:

/storage/websites/example.com/public/index.php

with:

<?php

$name = "CresignSys";

echo "<h1>Hello $name</h1>";

The browser requests:

/

The server executes PHP.

The browser receives:

<h1>Hello CresignSys</h1>

It does not normally receive:

$name = "CresignSys";

4. PHP Interpreter

Something must actually execute PHP code.

That component is the PHP interpreter/runtime.

Conceptually:

PHP file
   ↓
PHP runtime
   ↓
execution
   ↓
output

But where does PHP-FPM fit?


5. What Does FPM Mean?

FPM means:

FastCGI Process Manager

So:

PHP-FPM
=
PHP FastCGI Process Manager

It manages PHP worker processes that execute PHP applications.


6. Why Do We Need PHP-FPM?

Nginx is excellent at serving HTTP traffic.

But Nginx is not a PHP interpreter.

Therefore:

Browser
   ↓
Nginx
   ↓
PHP-FPM
   ↓
PHP

Nginx handles the web side.

PHP-FPM manages PHP execution.


7. Nginx and PHP-FPM Have Different Jobs

Nginx

Handles:

HTTP
TLS
routing
static files
connections
headers
reverse proxying

PHP-FPM

Handles:

PHP workers
PHP execution
worker lifecycle
PHP process management

WordPress

Handles:

pages
posts
plugins
themes
users
database queries
application logic

8. The Complete Flow

When somebody visits:

https://templates.cresignsys.com/about/

the simplified flow is:

Browser
   ↓
TLS
   ↓
HTTP
   ↓
Nginx
   ↓
FastCGI
   ↓
PHP-FPM
   ↓
PHP
   ↓
WordPress
   ↓
MySQL

Then the result travels back.


9. What Is FastCGI?

FastCGI is a protocol/interface for communicating between a web server and an application process manager.

Conceptually:

Nginx
  │
  │ FastCGI
  ▼
PHP-FPM

Nginx sends information about the HTTP request.

PHP-FPM passes it to a PHP worker.


10. Why Not Just Start PHP for Every Request?

Imagine:

Request 1
 ↓
start PHP
 ↓
execute
 ↓
stop PHP

Request 2
 ↓
start PHP
 ↓
execute
 ↓
stop PHP

That would introduce unnecessary process-start overhead.

PHP-FPM keeps a managed pool of workers.


11. Worker Processes

Think of PHP-FPM as a team of PHP workers.

PHP-FPM
│
├── Worker 1
├── Worker 2
├── Worker 3
├── Worker 4
└── Worker 5

Requests can be assigned to available workers.


12. Why Multiple Workers?

Suppose 10 users access WordPress simultaneously.

If only one PHP worker can execute requests:

Request 1
Request 2
Request 3
...

they may wait behind one another.

With multiple workers:

Request 1 → Worker 1
Request 2 → Worker 2
Request 3 → Worker 3
Request 4 → Worker 4

multiple requests can be processed concurrently.


13. But More Workers Isn’t Always Better

This is extremely important.

More workers consume:

RAM
CPU
database connections
file descriptors

Suppose each PHP worker uses significant memory.

If you configure:

100 PHP workers

on a small VPS, you may exhaust RAM.

Therefore:

PHP-FPM worker configuration must match the server’s resources and workload.


14. PHP-FPM Pool

PHP-FPM organizes workers into:

Pools

A pool might look conceptually like:

Pool: www
│
├── Worker
├── Worker
├── Worker
└── Worker

The pool configuration controls how those workers operate.


15. Default Pool

On Ubuntu/Debian systems, a common default pool is:

www

Its configuration is often under something like:

/etc/php/<version>/fpm/pool.d/www.conf

For example:

/etc/php/8.3/fpm/pool.d/www.conf

Your installed PHP version may differ.


16. Find Your PHP Version

Run:

php -v

You might see:

PHP 8.x.x

But remember:

CLI PHP and PHP-FPM can be configured differently.

So also inspect:

systemctl list-units --type=service | grep php

17. Find PHP-FPM Services

Try:

systemctl list-units --type=service | grep fpm

You may see something like:

php8.3-fpm.service

18. Check PHP-FPM Status

For a specific version:

sudo systemctl status php8.3-fpm

Replace 8.3 with your installed version.

You want something similar to:

Active: active (running)

19. PHP-FPM Socket

Nginx needs somewhere to send FastCGI requests.

A common configuration is:

/run/php/php8.3-fpm.sock

This is a Unix socket.


20. Check PHP Sockets

Run:

ls -la /run/php/

You may see:

php8.3-fpm.sock

or multiple versions:

php8.1-fpm.sock
php8.2-fpm.sock
php8.3-fpm.sock

21. Nginx Configuration

You may have something like:

location ~ \.php$ {
    include fastcgi_params;
    fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}

This creates the connection:

Nginx
  ↓
Unix socket
  ↓
PHP-FPM

22. What Is a Unix Socket?

A Unix socket is a local communication endpoint.

Instead of using:

127.0.0.1:9000

Nginx can communicate through:

/run/php/php8.3-fpm.sock

Both processes are on the same server.


23. TCP Alternative

PHP-FPM can also listen on a TCP address.

Conceptually:

Nginx
 ↓
127.0.0.1:9000
 ↓
PHP-FPM

This is different from:

Nginx
 ↓
Unix socket
 ↓
PHP-FPM

Both are valid architectures.


24. Why Unix Sockets Are Common

For same-machine communication, Unix sockets can be convenient and efficient.

They also avoid exposing PHP-FPM on a network port unnecessarily.


25. PHP-FPM Pool Configuration

A simplified pool might contain:

[www]

user = www-data
group = www-data

listen = /run/php/php8.3-fpm.sock

pm = dynamic

pm.max_children = 10
pm.start_servers = 2
pm.min_spare_servers = 2
pm.max_spare_servers = 5

This is an educational example, not a recommended production configuration for your particular server.


26. user

user = www-data

means worker processes run under that user.

This connects directly to our previous lesson.

PHP-FPM
 ↓
www-data
 ↓
Linux permissions

27. group

group = www-data

sets the worker process group.

Again:

User
+
Group
+
Filesystem permissions

determine what PHP can access.


28. listen

Example:

listen = /run/php/php8.3-fpm.sock

This tells PHP-FPM where to receive FastCGI connections.

Nginx must point to the corresponding endpoint.


29. The Socket Must Match

If Nginx says:

fastcgi_pass unix:/run/php/php8.3-fpm.sock;

but PHP-FPM is listening at:

/run/php/php8.2-fpm.sock

the connection will fail.

This can produce:

502 Bad Gateway


30. Classic 502 Problem

Browser
 ↓
Nginx
 ↓
PHP-FPM socket
      X

Possible reasons:

PHP-FPM stopped
Wrong socket
Wrong PHP version
Socket permissions
Pool configuration failure
PHP-FPM crashed

31. Check the Socket

Run:

ls -la /run/php/

Then compare it with:

sudo nginx -T | grep fastcgi_pass

This is a very useful diagnostic.


32. Process List

You can inspect PHP processes:

ps aux | grep php-fpm

or:

ps -ef | grep php-fpm

You may see:

root      php-fpm: master process
www-data  php-fpm: pool www
www-data  php-fpm: pool www
www-data  php-fpm: pool www

33. Master Process

PHP-FPM usually has a master process.

Conceptually:

PHP-FPM
│
└── Master
     │
     ├── Worker
     ├── Worker
     ├── Worker
     └── Worker

The master manages the worker pool.


34. Worker Process

Workers perform PHP application work.

For example:

HTTP request
 ↓
Nginx
 ↓
PHP-FPM
 ↓
Worker
 ↓
WordPress

35. pm

PHP-FPM has different process-management strategies.

Common modes include:

static
dynamic
ondemand

36. Static

With:

pm = static

PHP-FPM maintains a fixed number of workers.

Example:

pm.max_children = 10

means approximately 10 child workers.


37. Dynamic

With:

pm = dynamic

PHP-FPM dynamically manages the number of child processes within configured limits.

It uses settings such as:

pm.max_children
pm.start_servers
pm.min_spare_servers
pm.max_spare_servers

38. Ondemand

With:

pm = ondemand

workers can be created when requests arrive and removed after an idle period.

This can be useful for some low-traffic workloads.


39. pm.max_children

This is one of the most important settings.

Example:

pm.max_children = 10

It limits the number of child processes in the pool.

Conceptually:

Maximum concurrent PHP workers
=
10

40. Why It Matters

Suppose:

RAM = 4 GB

and PHP workers consume significant memory.

If you allow:

100 workers

the system can run out of memory.

Possible result:

RAM exhaustion
 ↓
swap pressure
 ↓
slow server
 ↓
process termination
 ↓
website failures

41. PHP-FPM and RAM

A simplified model:

PHP worker memory
×
number of workers
≈
PHP memory requirement

This is only an approximation because real memory usage varies.

But it gives you the right mental model.


42. CPU Also Matters

PHP workers consume CPU.

Suppose:

100 requests

all execute heavy WordPress operations.

Then:

PHP
 ↓
CPU saturation

can occur.

So PHP-FPM tuning is not just about RAM.


43. Database Connections

PHP workers may also interact with MySQL.

If you have:

50 PHP workers

you can potentially have many database interactions occurring concurrently.

Therefore:

PHP-FPM capacity

must be considered together with:

MySQL capacity

44. WordPress Request

Let’s follow one request.

Browser:

GET /about/

Nginx:

Request matches location /

Then:

try_files
 ↓
index.php

Then:

FastCGI
 ↓
PHP-FPM

Then:

PHP worker
 ↓
WordPress

45. WordPress Loads

WordPress may load:

wp-config.php
wp-settings.php
plugins
theme
core files

Then it initializes the application.


46. WordPress Queries MySQL

For example, WordPress may need:

Site settings
Posts
Pages
Menus
Users
Metadata
Plugin settings

So:

PHP
 ↓
MySQL
 ↓
results
 ↓
PHP

47. PHP Generates HTML

WordPress eventually produces:

<html>
<head>
...
</head>
<body>
...
</body>
</html>

Then:

PHP worker
 ↓
PHP-FPM
 ↓
Nginx
 ↓
Browser

48. One Request May Be Expensive

A request can involve:

Nginx
 ↓
PHP-FPM
 ↓
WordPress
 ↓
20+ plugins
 ↓
Theme
 ↓
MySQL
 ↓
External APIs
 ↓
HTML

That is why a “simple webpage” can involve significant server work.


49. PHP OPcache

PHP has an important performance feature:

OPcache

OPcache stores compiled PHP bytecode in shared memory.

Without OPcache, PHP may repeatedly parse/compile scripts.

Conceptually:

PHP source
 ↓
compile
 ↓
bytecode
 ↓
execute

With OPcache:

PHP source
 ↓
compile once
 ↓
OPcache
 ↓
reuse compiled code

50. Why OPcache Matters for WordPress

WordPress contains a large number of PHP files.

Plugins and themes add more.

OPcache can significantly reduce repeated compilation overhead.


51. Check OPcache

Run:

php -m | grep -i opcache

You can also inspect:

php -i | grep -i opcache

But remember that CLI PHP configuration may differ from FPM.


52. Check FPM PHP Configuration

A PHP-FPM process may use a configuration such as:

/etc/php/8.3/fpm/php.ini

while CLI PHP may use:

/etc/php/8.3/cli/php.ini

Therefore:

CLI PHP
≠
FPM PHP

necessarily.


53. Why This Matters

You might run:

php -i

and conclude:

PHP has this setting.

But your website may be running under PHP-FPM with a different configuration.

For website troubleshooting, inspect the FPM configuration.


54. php.ini

PHP configuration controls many runtime behaviors.

Examples include:

memory_limit
max_execution_time
upload_max_filesize
post_max_size
max_input_vars
date.timezone

55. memory_limit

Example:

memory_limit = 256M

This limits memory available to a PHP request under normal PHP memory accounting.

It does not mean:

Every PHP worker permanently consumes 256 MB.

Actual memory usage varies.


56. max_execution_time

Example:

max_execution_time = 60

This controls how long PHP code is allowed to execute under the relevant PHP semantics.

It is not a universal guarantee that every request will terminate exactly at that time because other layers also have timeouts.


57. upload_max_filesize

Example:

upload_max_filesize = 64M

This limits the size of an individual uploaded file at the PHP level.


58. post_max_size

Example:

post_max_size = 64M

This limits the maximum size of POST data PHP will accept.

It should generally be large enough relative to intended uploads.


59. Multiple Limits Exist

An upload can be restricted by several layers:

Browser
 ↓
Nginx
 ↓
PHP-FPM/PHP
 ↓
WordPress

For example:

Nginx client_max_body_size
PHP upload_max_filesize
PHP post_max_size
WordPress/application limits

The smallest effective limit can become the practical restriction.


60. Nginx vs PHP-FPM

This distinction is important:

Nginx
=
receives HTTP request
PHP-FPM
=
runs PHP
PHP
=
language/runtime
WordPress
=
application

61. PHP-FPM Does Not Equal WordPress

Think:

PHP-FPM
   ↓
can run
   ↓
any compatible PHP application

It isn’t specifically a WordPress service.

It can run:

WordPress
Laravel
Drupal
Magento
custom PHP

and many other PHP applications.


62. One PHP-FPM Pool Can Serve Multiple Sites

A basic server might use:

Nginx
 │
 └── PHP-FPM www pool
      ├── site1
      ├── site2
      └── site3

This is simple.

But for stronger isolation, separate pools/users can be used.


63. Multi-Tenant Hosting

This becomes important for your hosting platform.

Imagine:

CresignSys Hosting
│
├── Customer A
├── Customer B
├── Customer C
└── Customer D

You don’t necessarily want all customers’ PHP applications running with exactly the same privileges.

A stronger architecture might be:

Customer A
 ↓
PHP-FPM pool A
 ↓
user A

Customer B
 ↓
PHP-FPM pool B
 ↓
user B

64. Why Separate Users Matter

Suppose:

Customer A

has a vulnerable plugin.

If A’s PHP process runs as:

customerA

then Linux permissions can limit access to:

customerA's files

instead of:

all customer websites

This is an important multi-tenant security principle.


65. Shared www-data Model

A simpler model:

site A → www-data
site B → www-data
site C → www-data

is easier to manage.

But isolation is weaker.

A compromise of one application running under the same account can potentially access files writable/readable by that shared account.


66. Isolated Pool Model

A more isolated model:

site A → php-fpm pool A → userA
site B → php-fpm pool B → userB
site C → php-fpm pool C → userC

gives more control.

It is more complex to configure and manage.


67. This Is Where Hosting Panels Become Useful

Hosting panels automate:

User creation
Website creation
PHP-FPM pools
Nginx configuration
Permissions
SSL
Logs
Databases
Backups

Your CresignSys Hosting Platform is essentially moving toward building these capabilities yourself.


68. PHP-FPM Logs

Check service logs with:

sudo journalctl -u php8.3-fpm

For recent entries:

sudo journalctl -u php8.3-fpm -n 100

Replace the version with yours.


69. Follow Logs Live

sudo journalctl -u php8.3-fpm -f

Then make a website request.

You can observe whether PHP-FPM reports errors.


70. Nginx + PHP-FPM Debugging

If you receive:

502 Bad Gateway

use this sequence:

1. Is Nginx running?
2. Is PHP-FPM running?
3. Does the socket exist?
4. Does Nginx point to the correct socket?
5. Can Nginx connect to the socket?
6. Are socket permissions correct?
7. Does PHP-FPM report errors?

71. Check Service

systemctl status php8.3-fpm

72. Check Socket

ls -l /run/php/

73. Check Nginx Configuration

sudo nginx -T | grep -n fastcgi_pass

74. Check Nginx Errors

sudo tail -f /var/log/nginx/error.log

75. Check PHP-FPM Errors

sudo journalctl -u php8.3-fpm -f

76. This Gives a Complete Diagnostic Chain

Browser
   ↓
HTTP 502
   ↓
Nginx
   ↓
error.log
   ↓
PHP-FPM
   ↓
journalctl
   ↓
socket
   ↓
Linux permissions

Instead of randomly changing configuration, you identify the failing layer.


77. Test PHP Directly

Create a temporary test file only when needed and remove it afterward:

<?php
phpinfo();

For example:

/storage/websites/example.com/public/test.php

Then visit:

https://example.com/test.php

This shows the PHP environment used by the website.


78. Security Warning

phpinfo() exposes extensive environment information.

Do not leave it publicly accessible.

After testing:

rm /storage/websites/example.com/public/test.php

79. Better: Temporary Diagnostic Endpoint

For production environments, prefer safer diagnostics rather than leaving phpinfo() publicly available.

The principle is:

diagnostic information
 ↓
temporary
 ↓
restricted
 ↓
removed after use

80. PHP Version

Different PHP versions can behave differently.

For example:

PHP 8.1
PHP 8.2
PHP 8.3
PHP 8.4

Applications and plugins may have compatibility requirements.

Therefore a hosting platform must manage PHP versions carefully.


81. Multiple PHP Versions

A server can potentially have:

PHP 8.1
PHP 8.2
PHP 8.3
PHP 8.4

with different FPM services:

php8.1-fpm
php8.2-fpm
php8.3-fpm
php8.4-fpm

Then different websites can use different versions.


82. Example

siteA.com
 ↓
PHP 8.2 FPM

siteB.com
 ↓
PHP 8.3 FPM

siteC.com
 ↓
PHP 8.4 FPM

Nginx determines which PHP-FPM endpoint each website uses.


83. Why Hosting Providers Offer PHP Versions

Customers may have applications that require:

specific PHP version

A hosting platform therefore often offers:

PHP version selector

This is a significant feature for a commercial hosting system.


84. PHP Lifecycle

PHP versions eventually reach:

Active support
 ↓
Security support
 ↓
End of life

A hosting platform should avoid encouraging unsupported PHP versions unless there is a specific legacy requirement and appropriate risk management.


85. WordPress Compatibility

WordPress itself, themes, and plugins can have different compatibility requirements.

Therefore changing:

PHP 8.2 → 8.4

should be tested rather than done blindly on production websites.


86. PHP-FPM Is a Process Manager

Remember the full meaning:

PHP
=
language/runtime

FastCGI
=
communication protocol/interface

FPM
=
process manager

Together:

PHP-FPM
=
managed PHP execution through FastCGI

87. Deep Request Architecture

Now our architecture is:

Browser
   │
   ▼
HTTPS
   │
   ▼
Nginx
   │
   │ FastCGI
   ▼
PHP-FPM master
   │
   ▼
PHP worker
   │
   ▼
WordPress
   │
   ▼
MySQL

And the filesystem/security layer:

PHP worker
   │
   ▼
Linux user
   │
   ▼
Linux kernel
   │
   ▼
Filesystem

88. The Most Important Concepts

Memorize these:

PHP
=
server-side programming language/runtime

PHP-FPM
=
PHP process manager

FastCGI
=
communication mechanism between Nginx and PHP-FPM

Pool
=
group of PHP workers

Worker
=
process that executes PHP requests

Socket
=
communication endpoint

OPcache
=
compiled PHP bytecode cache

php.ini
=
PHP configuration

pm.max_children
=
maximum child workers for a pool

89. One Complete WordPress Request

Let’s put everything together.

User requests:

https://templates.cresignsys.com/about/

DNS

domain
 ↓
IP

TCP

client
 ↓
server:443

TLS

secure channel

HTTP

GET /about/
Host: templates.cresignsys.com

Nginx

server_name
 ↓
location /
 ↓
try_files

PHP-FPM

FastCGI
 ↓
PHP worker

WordPress

load WordPress
 ↓
plugins
 ↓
theme
 ↓
database

MySQL

query
 ↓
result

PHP

generate HTML

Nginx

send response

TLS

encrypt response

Browser

decrypt
 ↓
parse HTML
 ↓
render page

90. The Full Hosting Stack

You can now visualize your server as:

                         INTERNET
                            │
                            ▼
                           DNS
                            │
                            ▼
                         IP/Route
                            │
                            ▼
                        TCP / QUIC
                            │
                            ▼
                           TLS
                            │
                            ▼
                          HTTP
                            │
                            ▼
                          NGINX
                            │
                 ┌──────────┴──────────┐
                 │                     │
                 ▼                     ▼
             Static files          FastCGI
                                       │
                                       ▼
                                  PHP-FPM
                                       │
                                  ┌────┴────┐
                                  ▼         ▼
                               Worker 1   Worker 2
                                  │
                                  ▼
                              WordPress
                                  │
                                  ▼
                                MySQL
                                  │
                                  ▼
                              Filesystem
                                  │
                                  ▼
                             Linux Kernel
                                  │
                         ┌────────┴────────┐
                         ▼                 ▼
                        RAM               Disk

This is the core architecture of a traditional PHP WordPress hosting environment.


Lesson 044 Summary

The most important idea:

Nginx receives the web request; PHP-FPM provides managed PHP execution; WordPress is the PHP application.

The relationship is:

Nginx
  ↓
FastCGI
  ↓
PHP-FPM
  ↓
PHP worker
  ↓
WordPress
  ↓
MySQL

And PHP-FPM’s resources are controlled through:

workers
pools
memory
CPU
sockets
timeouts
PHP configuration
OPcache

For your own hosting platform, this is the layer where website performance, PHP version selection, resource limits, and multi-tenant isolation become major design considerations.


Next Lesson — 045

MySQL From the Absolute Basics — How WordPress Stores Everything

We will start from:

What is data?
What is a database?
What is SQL?
What is MySQL?
What is a table?
What is a row?
What is a column?
What is a primary key?
What is an index?

Then connect it directly to WordPress:

Browser
 ↓
Nginx
 ↓
PHP-FPM
 ↓
WordPress
 ↓
MySQL
 ├── wp_posts
 ├── wp_users
 ├── wp_options
 ├── wp_postmeta
 ├── wp_terms
 └── wp_usermeta

and trace exactly what happens inside MySQL when you create a WordPress page, user, plugin, menu, or post.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *