Not long ago, when CentOS 8 was officially discontinued, I spent several sleepless nights migrating five client server clusters to CentOS Stream 9. Back then, the biggest challenge wasn’t the installation itself. The hard part was making legacy PHP code run smoothly without devouring all the RAM while still handling growing traffic.
Many developers have the habit of simply running <a href="https://itfromzero.com/en/centos-vi-en/saving-a-server-at-2-am-a-detailed-guide-to-dnf-package-manager-on-rhel-rocky-linux.html">dnf</a> install php and leaving the default configuration as is. As a result, when traffic hits just a few dozen concurrent users, the server starts throwing 502 errors or the CPU spikes to 100%. This article shares the practical experience I’ve gathered to help your PHP applications undergo a total performance transformation.
Why Does the Default Configuration Slow Down PHP?
By default, parameters on CentOS Stream 9 are set to extremely conservative levels to prioritize compatibility. However, this safety inadvertently throttles hardware performance.
Here are three critical bottlenecks:
- PHP-FPM Pool: The default
dynamicmode often keeps the number of processes too low. During sudden traffic spikes, requests have to queue up for processing. - Neglecting OPcache: Without OPcache, PHP must read, parse, and recompile code for every single execution. This is an immense waste of CPU resources.
- Outdated Versions: Default repos sometimes don’t provide the latest PHP versions (like 8.3). You’ll miss out on JIT (Just-In-Time) improvements that significantly speed up processing.
Using Remi Repository: The Professional Standard
Don’t use the PHP version provided by the OS base repo. I always prioritize the Remi Repository because it’s updated quickly and remains highly stable.
Step 1: Proper PHP 8.x Installation
First, load the EPEL and Remi repos into your system:
# Install EPEL and Remi
sudo dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm
sudo dnf install -y https://rpms.remirepo.net/enterprise/remi-release-9.rpm
# Reset and enable PHP 8.2 (or 8.3)
sudo dnf module reset php -y
sudo dnf module enable php:remi-8.2 -y
# Install essential extensions
sudo dnf install -y php-fpm php-cli php-gd php-mysqlnd php-mbstring php-xml php-opcache php-zip php-curl
Step 2: Fine-tuning PHP-FPM to Handle High Loads
The configuration file you need to handle is located at /etc/php-fpm.d/www.conf. Never use default parameters for a production server.
To calculate pm.max_children, I usually use the formula: (Total RAM – System RAM) / 50MB (the average size of a PHP process). For a server with 4GB of RAM, setting it to around 60 processes is a safe bet.
Open the configuration file:
sudo vi /etc/php-fpm.d/www.conf
Adjust the following parameters to optimize response times:
pm = dynamic
pm.max_children = 60
pm.start_servers = 10
pm.min_spare_servers = 10
pm.max_spare_servers = 30
; Reset process after 500 requests to free up leaked RAM
pm.max_requests = 500
Pro Tip: If your server runs only one large website, switch to pm = static. This removes the latency caused by the system having to initialize new processes.
Step 3: Activating OPcache Power
OPcache stores bytecode in RAM, allowing PHP to respond almost instantaneously. A typical WordPress site can contain thousands of files, so the default configuration is insufficient.
Edit the /etc/php.d/10-opcache.ini file with these battle-tested parameters:
opcache.enable=1
; Increase to 256MB if you run many heavy plugins/frameworks
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
; WordPress needs at least 10000 to cache all system files
opcache.max_accelerated_files=10000
; In production environments, set to 60 seconds to reduce constant file checks
opcache.revalidate_freq=60
; Enable file cache for faster startup after a server reboot
opcache.file_cache=/var/lib/php/opcache
Step 4: Verify and Apply
Before restarting, check if you’ve made any typos:
sudo php-fpm -t
If it shows test is successful, activate the service:
sudo systemctl enable php-fpm
sudo systemctl restart php-fpm
Unix Socket: The Final Performance Boost
By default, PHP-FPM connects via port 9000 (TCP). If the Web Server and PHP are on the same machine, switch to using a Unix Socket. This bypasses the network layer overhead, increasing throughput by about 10-15%.
In www.conf, change the listen path:
listen = /run/php-fpm/www.sock
listen.owner = nginx
listen.group = nginx
listen.mode = 0660
Don’t forget to update your Nginx configuration to point to this .sock file instead of 127.0.0.1:9000.
Conclusion
There is no magic formula for PHP optimization that fits every configuration. For e-commerce systems requiring heavy calculations, I also enable JIT (Just-In-Time) to push performance to the limit.
My advice is to start with the parameters above, then monitor with htop. If RAM is still available but the CPU is overloaded, gradually increase pm.max_children. I hope these insights help your server run smoother and more reliably!

