Apache2 and php fpm performance optimization 2023

apache

I had to handle high-traffic loads a few months ago for my client and we were going through with downtime, not using memory, and a lot of trouble in my past. In this article, I want to give a step-by-step guide to apache2 performance settings, which is a concentrated result of a lot of reading and trying.

My environment

  • AWS EC2 (m4.xlarge): 4 *2,4GHz | 16GB RAM
  • Ubuntu 16.04
  • Apache 2.4 using mpm_event
  • PHP FPM (5.6, 7.4)

Precalculation of average memory usage and max clients/max-children

1. Calculate process size

You need to know how many processes can run on your machine. So calculating the process size of your main CPU/memory drivers is necessary.

There are several calculation methods out there. Personally, I prefer this Python script as it takes shared memory into account and will give insights into actual memory usage.

cd ~
wget https://raw.githubusercontent.com/pixelb/ps_mem/master/ps_mem.py
chmod a+x ps_mem.py
sudo python ps_mem.py

ps_mem.py will produce output like this:

Here you can see that there are 30 apache2 processes, consuming a total of 139MiB, so each Apache process uses roughly 5MiB of RAM. The PHP-fpm5.6 process will use about 50MiB.

2. Calculate Apache MaxRequestWorkers

To be safe though, I’ll reserve 15% of memory for all other processes (in my case ~2,4GiB) and round up Apache process size to 5MiB.

MaxRequestWorkers = (Total RAM - Memory used for Linux, DB, etc.) / process size
MaxRequestWorkers = (16384MB - 2400MB) / 5MB = 2800

3. Calculate php-fpm max-children

To be safe though, I’ll reserve 1 GiB for all other processes and round up the php process size to 55MiB.

maxclients = (Total RAM - Memory used for Linux, DB, etc.) / process size
maxclients = (16384MB - 2400MB) / 55MB = 256

I found, this Excel Sheet for the calculation: https://s3.buckpesch.io/downloads/apache_performance.xlsx

Detailed Setup

In the /etc/apache2/mods-enabled/mpm-event.conf or /etc/apache2/mods-enabled/mpm-worker.conf file:

<IfModule mpm_*_module>
  ServerLimit           (Total RAM - Memory used for Linux, DB, etc.) / process size
  StartServers          (Number of Cores)
  MinSpareThreads       25
  MaxSpareThreads       75
  ThreadLimit           64
  ThreadsPerChild       25
  MaxRequestWorkers     (Total RAM - Memory used for Linux, DB, etc.) / process size
  MaxConnectionsPerChild   1000
</IfModule>

Note that the default settings did not contain the “ServerLimit”, so I added it here.

In the /etc/php/7.4/fpm/pool.d/www.conf change the following locations:

pm = dynamic            
pm.max_children         (total RAM - (DB etc) / process size)
pm.start_servers        (cpu cores * 4)
pm.min_spare_servers    (cpu cores * 2)
pm.max_spare_servers    (cpu cores * 4)
pm.max_requests         1000

To learn about all php-fpm settings I recommend watching the video on that page: https://serversforhackers.com/c/php-fpm-process-management

My final settings

My server has 16GB RAM and 4 CPUs à 2,4GHz. My average apache process has 5MB, and an average PHP process takes 55MB.

/etc/apache2/mods-available/mpm_event.conf

# Optimized settings for avg. apache process 15MB and AWS EC2 m4.xlarge Server
<IfModule mpm_event_module>
        ServerLimit              2800
        StartServers             4
        MinSpareThreads          25
        MaxSpareThreads          75
        ThreadLimit              64
        ThreadsPerChild          25
        MaxRequestWorkers        2800
        MaxConnectionsPerChild   1000
</IfModule>

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

; Optimized for php-fpm request size of 55MB on AWS EC2 m4.xlarge (4CPU cores, 16GB RAM)
pm = dynamic
pm.max_children = 256
pm.start_servers = 20
pm.min_spare_servers = 10
pm.max_spare_servers = 20
pm.max_requests = 1000

Save your settings and restart your Apache and php-fpm processes

sudo service apache2 restart
sudo service php7.4-fpm restart

Also, read Enable HTTP/2 with Apache in Ubuntu 2023

Test you settings

To test your server settings you can run Apache Bench tests and see how your server behaves in htop .

Open 2 terminals and the following command to test 5000 requests with a concurrency of 100 parallel requests:

ab -n 5000 -c 100
AmritMatti

I’m the owner of “DevOpsTechy.online” and been in the industry for almost 5 years. What I’ve noticed particularly about the industry is that it reacts slowly to the rapidly changing world of technology. I’ve done my best to introduce new technology into the community with the hopes that more technology can be utilized to serve our customers. I’m going to educate and at times demonstrate that technology can help businesses innovate and thrive. Throwing in a little bit of fun and entertainment couldn’t hurt right?

AmritMatti

I’m the owner of “DevOpsTechy.online” and been in the industry for almost 5 years. What I’ve noticed particularly about the industry is that it reacts slowly to the rapidly changing world of technology. I’ve done my best to introduce new technology into the community with the hopes that more technology can be utilized to serve our customers. I’m going to educate and at times demonstrate that technology can help businesses innovate and thrive. Throwing in a little bit of fun and entertainment couldn’t hurt right?

View all posts by AmritMatti →

Leave a Reply

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