Tweaking PHP-FPM and Apache for Amazon Linux t2.micro instance

This is related to switching PHP to FastCGI mode in my previous post.

After successfully switching my apache server to MPM mode and updating PHP to use FastCGI, I noticed my server would completely stop responding either to web site or SSH connection after some time. The only solution to this problem seem to be stopping the EC2 instance and starting it back up. Simply restarting would not work as the instance would not restart. So digging around and doing some googling led me to believe it is related to memory issue. As in t2.micro instance was running out of memory trying to serve all requests. Once a server runs out of memory, it should use swap to free up some memory to keep itself running. Except that t2.micro instance does not have a swap partition by default. Instead of upgrading the instance to one with larger memory which would increase the associated cost, I tried some tweaks to the configuration of apache and PHP to see if it would resolve this issue. (You could attempt creating a swap partition to see if it helps with the memory issue, but I have not tried it and tweaking configuration is an easier task)

PHP-FPM

On the PHP’s side of things, take a look at your PHP-FPM’s configuration. On my hosting setup, the configuration file was in /etc/php-fpm-7.0.d/www.conf. The thing is t2.micro EC2 instance does not have a lot of memory. It has 1GB to be precise. The number of children processes you can run depends on how much memory each child process takes up. However, if your static or dynamic configuration is not able to handle the number of request, you might get a warning in your PHP-FPM’s error.log like:

WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 8 children, there are 3 idle, and 15 total children

or like:

WARNING: [pool www] server reached max_children setting (30), consider raising it

For a low memory server and low traffic web site, ondemand makes more sense as there will be enough down time to free up memory by killing idle children processes and the slight delay when spawning a child process is not a critical factor. So below is my recommendation of PHP-FPM running on t2.micro instance.

pm = ondemand
pm.max_children = 30 ;set this to between 30 or 40 depending on your website traffic
pm.process_idle_timeout = 10s;
pm.max_requests = 500

Apache

MaxConnectionsPerChild Directive description in Apache document says:

The MaxConnectionsPerChild directive sets the limit on the number of connections that an individual child server process will handle. After MaxConnectionsPerChild connections, the child process will die. If MaxConnectionsPerChild is 0, then the process will never expire.
Setting MaxConnectionsPerChild to a non-zero value limits the amount of memory that process can consume by (accidental) memory leakage.

This configuration will help maintain enough free memory in your server, so it doesn’t get bogged down when on low memory. Default value is 0 which means child process will never die. I recommend setting it to 1000 for t2.micro instance. I’ve set the directive in /etc/httpd/conf.modules.d/00-mpm.conf.

Restart both httpd and php-fpm service after changes are made.

Continue to monitor your web site and your server’s memory utilization. Check error logs and messages log periodically to make sure everything is running without a hitch.

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.