Why so much RAM used on website?

I build and host websites. I switched to using Wordpress last year mostly, from other systems like Expression Engine. My Expression Engine hosted sites tend to have an approx. of 20Mb to 50Mb RAM usage according to Longview, and < 0.2% CPU. Wordpress sites have like 400Mb to 400Mb. And higher CPU from 1% to 10%.

Its really bugging me, I want to reduce server resources. Sometimes the server runs out of memory and Apache crashes, but I dont have that many sites on it. I put it down to all this high memory used by WP.

Yesterday we went live with a website that has 0 visitors as its a new domain, and not been advertised. During 0 visitors Memory is still up around 300Mb and 3% CPU according to Longview. I have disabled Wordpress built in cron so with zero visitors I dont understand why the user for this website is using so much RAM. There is no email on it, just the website.

Here is htop right now, 0 visitors:

PID USER PRI NI VIRT RES SHR S CPU% MEM% TIME+ Command

8722 storiesfr 20 0 291M 94724 16328 S 0.0 1.2 0:25.79 /opt/rh/rh-php70/root/usr/bin/php-cgi

7686 storiesfr 20 0 290M 94304 16484 S 0.0 1.2 0:24.47 /opt/rh/rh-php70/root/usr/bin/php-cgi

16941 storiesfr 20 0 278M 84912 15196 S 0.0 1.0 0:03.21 /opt/rh/rh-php70/root/usr/bin/php-cgi

Lonview reports average 200Mb to 300Mb past 30 minutes.

Does anyone know why RAM and CPU is high in Longview for a site with 0 visitors? What other things could this user on the server be doing to use so much? Or is it a red herring as I can see from top its VIRT that is high, but RES is less than 100Mb. So would RES be the important one? Is Longview not good enough to use as its showing total RAM including VIRT?

Saying all that, one of my Expression Engine sites with more visitors on at the moment, is showing 26Mb RAM in Longview, but in top its similar figures to the one above, 292Mb VIRT, 26900 RES, 19552 SHR, but 0 CPU, 0.3% MEM.

So its all a bit confusing how to identify what the actual RAM usage is and then whats causing it.

Thanks

13 Replies

RES is the important figure. I have a 2 GB Linode that has 16 low traffic (eight dev, eight live) WordPress websites on it, plus it serves mp3s for a podcast, and it uses approx. 900 MB of RAM. Current top usage:

 2994 mysql     20   0 1463.8m 310.9m   9.6m S  0.0 15.6  18:35.35 mysqld                      
20077 www-data  20   0  884.3m 147.2m   7.6m S  0.0  7.4  25:03.92 mega-cmd-server             
29252 www-data  20   0  479.2m  49.8m  37.8m S  0.0  2.5   0:00.08 php-fpm7.2                  
20826 www-data  20   0  565.5m  38.7m   6.5m S  0.0  1.9   0:44.48 nginx                       
 3467 root      20   0  115.2m  32.3m   4.9m S  0.0  1.6   3:45.77 linode-longview             
20810 root      20   0  474.1m  30.1m  24.2m S  0.0  1.5   0:03.14 php-fpm7.2                  
 3431 memcache  20   0  342.8m  27.5m   1.8m S  0.0  1.4   0:34.58 memcached                   
20827 www-data  20   0  286.2m  13.5m   2.6m S  0.0  0.7   0:00.20 nginx                       
20824 root      20   0  286.2m  12.6m   2.0m S  0.0  0.6   0:00.00 nginx

... 

Remove the 147 MB used by MEGAcmd (I use my MEGA account as an extra layer of backups - https://github.com/meganz/megacmd) and this drops to approx. 750 MB (40% of that is MariaDB/mysql, which is normal for a WordPress server). I do run my own custom WordPress multitenancy setup (so much better than WordPress multisite), but that's irrelevant really, it just saves on disk usage and doing WordPress core and plugin updates for 16 separate installs rather than RAM usage. The one suggestion I give to people wanting to operate their own servers for WordPress is to avoid Apache (RAM/resources hog) and use nginx with PHP-FPM, which uses far less RAM and fewer resources and is considerably faster and more efficient. Use nginx's built-in FastCGI cache for page caching and the server will be able to handle huge amounts of traffic without issue (I have never experienced an OOM error using nginx/PHP-FPM with WordPress).

I started with EasyEngine https://easyengine.io to get everything up and running in as little time as possible, but have gradually honed my setup to my liking e.g. multitenancy over the last couple of years. I'm really happy with it and it'll handle many more WordPress websites before I have to think about upgrading to a larger Linode.

Thanks. Easyengine looks good. but I use Virtualmin/Webmin to manage servers, I dont think its compatible. Next time I create a new server I will install Nginx I think, that can be done with Virtualmin. But I am stuck with Apache on these sites for now. I just dont understand why it uses so much RAM with caching plugins. I have since installed WP Rocket. The speed boost is amazing, so much better than Super Cache. You'd think with such fast caching the system behind the scenes cant be processing much RAM but the RAM has not dropped since using this caching plugin. I am just amazed how WP uses 5 to 10x more RAM than Expression Engine.

I was asked to look at a website that had problems with too much RAM and CPU usage. It was a simple server running Virtualmin/Webmin hosting a single website. Apparently, Virtualmin/Webmin was horribly convoluted, it run both nginx and apache at the same time, nginx forwarding to apache at another port, both doing caching and the two of them combined caused all the problems. Once I removed nginx and setup apache properly, everything run perfectly with no unnecessary resource usage.

eventually, I found Virtualmin/Webmin an overkill to run a single website, so I converted the server to plain vanilla CentOS 7, without a control panel.

Control panels are designed for people who don't much care for the technical quality and are almost always a hindrance when compared with custom configuration. Tools exist that make mass management of websites easier and repeatable without degrading the degree of control.

@emestee, well said

my tool of choice and my control panel at the same time is….. Ansible :)

````
emestee@devbox:~/src/ansible$ wc -l hosts
103 hosts

````

Ditto :D

with one command, I can destroy all my servers at once!

ansible = WMSD (weapon of mass server destruction)

just joking, its a great tool if used properly.

But the control panel RAM and CPU is no where to be seen in the top list of high usage, its all websites. I dont have nginx. I have a lot of non-WP sites on there who's RAM is fine. So the high RAM usage is only WP sites, everything else is OK. Occasional high clamscan. The control panel itself doesn't consume much especially when not using it.

mysql us using the highest memory acdording to "top -o RES", about 421Mb, but I'm specifically looking at why WP uses high memory as the combines memory of WP sites is far greater than MySQL, there is far more to be gained if WP memory can be reduced.

Also, my reported WP RAM usage is coming from Longview… which reports much higher RAM for past 30 minutes than top RES does. Oh, actually maybe due to top showing multiple processes per user, and longview showing only 1.

Under FPM, the memory use will depend on your pm.* configuration. If Apache sometimes crashes with OOMs, then:

1) Allow more FPM children but lower the limit of requests per child. In general, PHP tends to be memory-leaky, and restarting children often is almost always a good idea. Frequent children restarts will keep this problem in check.

2) Profile the PHP code itself, you well may have a plugin that does something really stupid

3) Increase the OS swap

4) Test performance with Apache ab to see where's your concurrency cutoff point, then tweak pm.* settings to improve performance

> 1) Allow more FPM children but lower the limit of requests per child. In general, PHP tends to be memory-leaky, and restarting children often is almost always a good idea. Frequent children restarts will keep this problem in check.
Actually MySQL (Mariadb) seems to the one that is crashing most, its often oom kills on it.

> 2) Profile the PHP code itself, you well may have a plugin that does something really stupid
There are not any plugins for Wordpress that do this anymore. There used to be one GoDaddy made everyone raved about, but they stopped development and it no longer works.

> 3) Increase the OS swap
I thought I read some time ago I should not do that on Linodes?

> 4) Test performance with Apache ab to see where's your concurrency cutoff point, then tweak pm.* settings to improve performance
I use apachebench but doesnt recommend any changes, it outputs the config I have.

OOM killing a process is not an indication that this process is consuming too much memory, only that at the given moment it asked for more memory that can be allotted (because another process hogged it). You can (and should) do memory calculations that allocate e.g. 30% of RAM to mysql and 60% to Apache and impose configuration restrictions on both. The exact proportion is derived from experimentation and knowing your particular application's profile. You can also impose restrictions on the system level via ulimit, cgroups etc but those are last resort.

I would still blame PHP before anything else because it's rather trivial to write scripts that, under multiple executions, hog all available memory. If this is compounded with locking or blocking IO (e.g. calling a very slow foreign API) and the webserver FPM memory contraints not configured properly, then the exact thing you're describing would happen.

Yes, you should have spare swap memory because your only other alternative is a very strict configuration that carefully constrains memory use; simply put without swap any spontaneous load spike is liable to crash your services, which in turn often creates a snowball effects as requests pile up and systemd restarts the services. There is no meaningful performance impact in having swap enabled; you can finetune this impact by playing with kernel swappiness settings (under vm.* in sysctl IIRC)

AB will not recommend you changes; it will show you performance given some concurrency and velocity. You determine a cutoff point by assuming some values for -c and -n (for example -c 10 -n 50) and then increasing both values slightly until you see a significant increase in response times. Do this twice, one for static files and one for some PHP script that adequately represents an average request to your PHP code.

Once you know where the cutoff point is, you can start experimenting with the webserver and FPM settings and see how they affect the cutoff.

Reply

Please enter an answer
Tips:

You can mention users to notify them: @username

You can use Markdown to format your question. For more examples see the Markdown Cheatsheet.

> I’m a blockquote.

I’m a blockquote.

[I'm a link] (https://www.google.com)

I'm a link

**I am bold** I am bold

*I am italicized* I am italicized

Community Code of Conduct