Last week we updated several wordpress sites which are running Alpine Linux as containers inside a host (Ubuntu 20.04) through LXD.
A summary of the update is as follows:
Alpine Linux v3.8 -> 3.14
PHP 5.3.6 -> 7.4.24
Wordpress 5.0.3 -> 5.7.3
Problem
We started having issues with the server performance after those updates and we discovered that the updated containers were using 3 times or more memory (resident memory) than the older ones (about 150MB vs 50MB), which caused the server to start swapping more often.
In the older versions (using PHP 5.3), the memory used by php
(process) increases as the page is being processed (as expected), but just after it finishes, it goes back to normal. In other words, something like: 10MB
---> 95MB
---> 10MB
.
In the updated containers, the memory used by php
increases in the same way, but it does not go back to "normal": 10MB
---> 95MB
---> 95MB
. And each time a new process is used, the same happens, increasing the memory usage by the number of available child processes (which in this case are 4 per site).
What I have tried
- Downgrading the PHP version up to
7.2.x
and7.3.x
: same thing - Updated to
php 8.0.11
: same problem - Using
apache2
instead oflighttpd
(currently php is running as fcgi) : same behavior - Updating only Alpine and PHP to identify if Wordpress may be the cause : wordpress is not the cause
- Running wordpress without plugins (to know if some plugin may be causing an issue) : no change
- Executed a simple concatenation loop (pure php) : same thing
- Tested in a different server with a different wordpress site : same behavior
What is the reason it is not recovering the memory? How can it be fixed?
Update
- I setup a clean
Alpine 3.14
container and performed the "simple loop" test. In that case, the resident memory was reduced as expected. However, once I tested with an actual wordpress site, the problem persisted. - I setup a clean
Ubuntu 20.04
container and did the same tests. The result was the same as with the cleanAlpine 3.14
.
According to this bug report it is not really a bug, but a feature in PHP7+ under the Zend Engine Memory Management:
The suggested solution is to call: gc_mem_caches(). You can use
auto_prepend_file
andauto_append_file
directives inphp.ini
to execute it always if needed.However that solution didn't help in my situation, so it is not a warranty that it will work.
As there is no easy way to change that behavior at the current moment, I found another way to solve the memory issue (it should work for PHP7,PHP8):
php-cgi
, usephp-fpm
ondemand
mode ordynamic
:/etc/php7/php-fpm.d/www.conf
:or:
The main difference between them is that
ondemand
will use less memory when idle, but it will be slower when a client connects.This is a comparison of my results:
Values in the table are approximate and only for illustration purposes (not a real benchmark in any way).