• Skip to secondary menu
  • Skip to main content
  • Skip to primary sidebar
  • Home
  • Projects
  • Products
  • Themes
  • Tools
  • Request for Quote

Vengala Vinay

Having 12+ Years of Experience in Software Development

  • Home
  • WordPress
  • PHP
    • Codeigniter
  • Django
  • Magento
  • Selenium
  • Server
Home » Installing and Configuring Apache with Event MPM and PHP 8.2-FPM on RHEL 9: Complete Performance Playbook

Installing and Configuring Apache with Event MPM and PHP 8.2-FPM on RHEL 9: Complete Performance Playbook

System Preparation and Package Installation

This guide assumes a clean RHEL 9 installation. We will leverage the AppStream repository for Apache and PHP, ensuring we get well-supported versions. Prior to installation, it’s prudent to update the system to the latest packages.

Execute the following commands to update your system and install the necessary components:

sudo dnf update -y
sudo dnf install -y httpd php php-fpm php-cli php-common php-mysqlnd php-gd php-xml php-mbstring php-opcache

The `php-fpm` package is crucial for integrating PHP with Apache using the FastCGI Process Manager. `php-opcache` is essential for performance by caching compiled PHP bytecode.

Apache Configuration: Enabling Event MPM

RHEL 9’s default Apache installation typically uses the `worker` MPM. For high-concurrency scenarios, the `event` MPM offers superior performance by leveraging non-blocking I/O for keep-alive connections, allowing worker threads to handle new requests more efficiently. We need to disable the `worker` MPM and enable the `event` MPM.

First, locate the MPM configuration files. These are usually found in /etc/httpd/conf.modules.d/.

sudo dnf module list httpd
sudo dnf module enable httpd:2.4
sudo dnf install -y httpd

Now, we’ll disable the `worker` MPM and enable the `event` MPM. This involves manipulating symbolic links within the Apache configuration directory.

sudo systemctl stop httpd
sudo dnf module disable httpd
sudo dnf module enable httpd:2.4
sudo dnf install -y httpd
sudo systemctl enable httpd
sudo systemctl start httpd

Verify the MPM is loaded:

sudo apachectl -V | grep -i "server mpm"

The output should indicate MPM event.

Tuning Apache Event MPM Parameters

The performance of the `event` MPM is heavily influenced by its configuration directives. These are typically found in /etc/httpd/conf.modules.d/00-mpm.conf or a similar file. We will adjust key parameters for optimal concurrency.

Edit the MPM configuration file. The exact path might vary slightly, but look for the section related to the `event` MPM.

# /etc/httpd/conf.modules.d/00-mpm.conf (Example snippet)

<IfModule event.c>
    # Start with a reasonable number of threads per process.
    # This value should be tuned based on your server's CPU cores and memory.
    # A good starting point is 25-50 threads per core.
    ThreadsPerChild 100

    # MaxRequestWorkers defines the maximum number of requests that can be served
    # simultaneously. This is calculated as:
    # MaxRequestWorkers = ServerLimit * ThreadsPerChild
    # We'll set ServerLimit to a reasonable value and let MaxRequestWorkers be derived.
    # For a 16-core server, starting with ServerLimit 16 is sensible.
    ServerLimit 16

    # MaxConnectionsPerChild: The maximum number of connections that a child
    # process will handle before it dies and is replaced.
    # Setting this too low can cause excessive process churn.
    # Setting it too high can lead to memory leaks in long-running processes.
    # A value between 10,000 and 50,000 is common.
    MaxConnectionsPerChild 20000
</IfModule>

After modifying the configuration, restart Apache:

sudo systemctl restart httpd

Tuning Strategy:

  • ThreadsPerChild: This is the number of threads each Apache process will spawn. Start with a value that is a multiple of your CPU cores (e.g., 25-50 threads per core). Monitor CPU and memory usage. If threads are constantly busy and CPU is high, increase this. If memory is exhausted, decrease it.
  • ServerLimit: This directive sets the maximum value for ThreadsPerChild. It also limits the number of child processes. The total number of concurrent requests is ServerLimit * ThreadsPerChild. Ensure this product does not exceed your available RAM.
  • MaxConnectionsPerChild: This prevents memory leaks in long-running processes. A value of 10,000 to 50,000 is a good range. If you experience memory issues, consider lowering this.

PHP-FPM Configuration and Tuning

PHP-FPM runs as a separate service and communicates with Apache via a FastCGI socket. Its configuration is critical for PHP application performance. The main configuration file is typically located at /etc/php-fpm.d/www.conf.

First, ensure the PHP-FPM service is enabled and started:

sudo systemctl enable php-fpm
sudo systemctl start php-fpm

Now, let’s tune the PHP-FPM pool configuration. We’ll focus on the `[www]` pool, which is the default.

; /etc/php-fpm.d/www.conf

; Choose the process management strategy.
; 'dynamic' is recommended for most environments.
; 'static' can offer slightly better performance but requires more upfront tuning.
; 'ondemand' is for very low traffic sites.
pm = dynamic

; If pm is 'dynamic', these configure the dynamic process management.
; pm.max_children: The maximum number of children that can be started.
; This should be tuned based on available RAM and expected load.
; A common starting point is (total RAM - OS/Apache overhead) / average PHP process size.
; For a 16GB server, with Apache using ~1GB, and PHP processes ~30MB, you might start with 200-300.
pm.max_children = 250

; pm.start_servers: The number of script processes to create when PHP-FPM starts.
pm.start_servers = 5

; pm.min_spare_servers: The minimum number of idle script processes.
pm.min_spare_servers = 2

; pm.max_spare_servers: The maximum number of idle script processes.
pm.max_spare_servers = 10

; pm.process_idle_timeout: The number of seconds after which an idle process will be killed.
; Set to '10s' or '15s' to prevent too many idle processes.
pm.process_idle_timeout = 10s

; pm.max_requests: The number of requests each child process should execute before respawning.
; This is similar to Apache's MaxConnectionsPerChild and helps prevent memory leaks.
; A value between 500 and 1000 is typical.
pm.max_requests = 500

; The address on which to accept FastCGI requests.
; For Apache with event MPM, using a Unix socket is generally faster than TCP/IP.
; Ensure the user Apache runs as (e.g., apache) has permissions to access this socket.
listen = /run/php-fpm/www.sock

; Set the user and group for the FPM pool.
user = apache
group = apache

; Set the permissions for the socket.
listen.owner = apache
listen.group = apache
listen.mode = 0660

; Set the maximum amount of memory a script may consume.
; Adjust based on your application's needs.
memory_limit = 256M

; Set the maximum execution time for scripts.
max_execution_time = 60

; Enable OPcache for bytecode caching.
; Ensure php-opcache is installed.
opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.revalidate_freq=2
opcache.validate_timestamps=1
opcache.enable_cli=1

After making these changes, restart PHP-FPM:

sudo systemctl restart php-fpm

Tuning Strategy for PHP-FPM:

  • pm: dynamic is usually the best balance. static can be faster if you can accurately predict load and have ample RAM, but it consumes resources even when idle.
  • pm.max_children: This is the most critical parameter. Over-allocating will lead to Out-Of-Memory errors. Under-allocating will lead to request queuing and slow response times. Calculate this based on your server’s RAM and the average memory footprint of a PHP process.
  • pm.max_requests: Essential for preventing memory leaks. A lower value means more frequent process respawning, which has a small overhead but ensures stability.
  • listen: Using a Unix socket (/run/php-fpm/www.sock) is generally preferred over a TCP port for performance and security when Apache and PHP-FPM are on the same server. Ensure correct permissions.
  • OPcache Settings: These are vital for PHP performance. Adjust opcache.memory_consumption based on your application’s complexity and the number of files. opcache.max_accelerated_files should be set high enough to cache all your application’s PHP files. opcache.revalidate_freq controls how often OPcache checks for file changes; set to 0 in production if you deploy manually and want maximum performance, or a small value (like 2) if you have frequent deployments and want automatic revalidation.

Apache Virtual Host Configuration for PHP-FPM

To enable PHP processing via PHP-FPM, we need to configure Apache’s virtual host to use the FastCGI interface. This involves setting up a ProxyPassMatch directive pointing to the PHP-FPM socket.

Edit your virtual host configuration file. For a default setup, this might be /etc/httpd/conf.d/your_site.conf or /etc/httpd/conf/httpd.conf.

# Example Virtual Host Configuration
<VirtualHost *:80>
    ServerName your_domain.com
    DocumentRoot /var/www/your_site

    # Enable .htaccess overrides if needed
    AllowOverride All

    # Configure Apache to use PHP-FPM via FastCGI
    <FilesMatch "\.php$">
        SetHandler "proxy:unix:/run/php-fpm/www.sock|fcgi://localhost/"
    </FilesMatch>

    # Optional: For Apache 2.4.10+ you can use ProxyFCGISetEnvIf
    # ProxyFCGISetEnvIf "REQUEST_URI" "^/.*" PHP_VALUE "display_errors=1"

    # DirectoryIndex for PHP files
    DirectoryIndex index.php index.html

    ErrorLog /var/log/httpd/your_site_error.log
    CustomLog /var/log/httpd/your_site_access.log combined

    # Optional: Apache performance tuning directives
    # KeepAlive On
    # KeepAliveTimeout 5
    # MaxKeepAliveRequests 100
</VirtualHost>

Ensure the DocumentRoot exists and has appropriate permissions for the Apache user (e.g., apache).

sudo mkdir -p /var/www/your_site
sudo chown -R apache:apache /var/www/your_site
sudo chmod -R 755 /var/www/your_site

After configuring the virtual host, test Apache’s configuration and restart the service:

sudo apachectl configtest
sudo systemctl restart httpd

Security Considerations and SELinux

SELinux can prevent Apache from communicating with the PHP-FPM socket if not configured correctly. We need to allow Apache to connect to the PHP-FPM socket.

# Allow Apache to connect to the PHP-FPM socket
sudo setsebool -P httpd_can_network_connect 1
sudo semanage fcontext -a -t httpd_var_run_t "/run/php-fpm/www.sock"
sudo restorecon -Rv /run/php-fpm/www.sock

It’s also good practice to restrict access to sensitive configuration files and ensure Apache runs with minimal privileges. The default `apache` user and group are generally appropriate.

Performance Monitoring and Further Tuning

Continuous monitoring is key to maintaining optimal performance. Use tools like:

  • top or htop: To monitor overall CPU and memory usage by Apache and PHP-FPM processes.
  • apachectl status: Provides basic Apache server status information.
  • php-fpm -m: Lists loaded PHP modules.
  • php -i: Detailed PHP information, including OPcache status.
  • Application Performance Monitoring (APM) tools: Such as New Relic, Datadog, or Prometheus/Grafana for in-depth application-level performance insights.

Tuning Iterations:

  • High CPU Usage: If top shows consistently high CPU usage by Apache or PHP-FPM, you might need to reduce ThreadsPerChild or pm.max_children, or investigate inefficient application code.
  • High Memory Usage: If the server is running out of memory, decrease ThreadsPerChild, pm.max_children, or opcache.memory_consumption. Ensure MaxConnectionsPerChild and pm.max_requests are set appropriately to mitigate memory leaks.
  • Slow Response Times: This could indicate insufficient worker processes (increase ThreadsPerChild/pm.max_children), slow application logic, or I/O bottlenecks.

Remember to restart Apache and PHP-FPM after making any configuration changes and always test thoroughly in a staging environment before deploying to production.

Reader Interactions

Leave a Reply Cancel reply

You must be logged in to post a comment.

Primary Sidebar

A little about the Author

Having 12+ Years of Experience in Software Development, Vinay is a principal software architect, senior systems engineer, and elite technical consultant. He specializes in bespoke PHP/WordPress development, high-performance Magento 2 & Shopify architectures, custom plugin/theme development from scratch, and legacy code modernization (including VB6, VB.NET, PyQt, and Crystal Reports). Known for solving complex database bottlenecks, speed optimization (Core Web Vitals), and advanced security code auditing, Vinay engineers production-ready systems designed to scale under heavy concurrent load conditions.



Chat on WhatsApp

Recent Posts

  • Debugging Guide: Diagnosing PHP-FPM child process pool exhaustion in multi-site network environments with modern tools
  • Debugging and Resolving complex namespace class loading collisions issues during heavy concurrent database traffic
  • Step-by-Step Guide: Offloading high-frequency customer support tickets metadata writes to a Redis KV store
  • How to refactor legacy event ticket registers queries using modern WP_Query and custom Transient caching
  • Step-by-Step Guide: Offloading high-frequency member profile directories metadata writes to a Redis KV store

Categories

  • apache (1)
  • Business & Monetization (390)
  • Centos (4)
  • Comparisons & Decision Making (55)
  • Debian (2)
  • Debugging & Troubleshooting (662)
  • Desktop Applications (14)
  • DevOps (7)
  • DevOps & Cloud Scaling (962)
  • Django (1)
  • Laravel (4)
  • Migration & Architecture (192)
  • Mobile Applications (24)
  • MySQL (1)
  • Performance & Optimization (873)
  • PHP (5)
  • PHP Development (49)
  • Plugins & Themes (244)
  • Programming Languages (9)
  • Python (20)
  • Ruby on Rails (1)
  • Security & Compliance (647)
  • SEO & Growth (492)
  • Server (118)
  • Ubuntu (9)
  • VB6 & VB.NET (8)
  • Web Applications & Frontend (19)
  • Web Assembly (Wasm) (2)
  • WordPress (22)
  • WordPress Plugin Development (726)
  • WordPress Theme Development (357)

Recent Posts

  • Debugging Guide: Diagnosing PHP-FPM child process pool exhaustion in multi-site network environments with modern tools
  • Debugging and Resolving complex namespace class loading collisions issues during heavy concurrent database traffic
  • Step-by-Step Guide: Offloading high-frequency customer support tickets metadata writes to a Redis KV store

Top Categories

  • DevOps & Cloud Scaling (962)
  • Performance & Optimization (873)
  • WordPress Plugin Development (726)
  • Debugging & Troubleshooting (662)
  • Security & Compliance (647)
  • SEO & Growth (492)

Our Products

  • ERP & LMS Systems (4)
  • Directories & Marketplaces (4)
  • Healthcare Portals (3)
  • Point of Sale (POS) (2)
  • E-Commerce Engines (2)

Our Services

  • E-Commerce Development (10)
  • WordPress Development (8)
  • Python & Desktop GUI (7)
  • General Consulting (7)
  • Legacy Modernization (5)
  • Mobile App Development (4)

Copyright © 2026 · Vinay Vengala