On our server we have a LOT of RAM for our traffic levels (16GB). The HTTP processes regularly eat up all CPU and need to be restarted without even getting close to using swap memory, so I'm looking for ways to spend RAM to ease the load on Apache (and/or help the seperate MySQL server which may be breaking Apache).

I have many WordPress installs on the HTTPD instance so APC sometimes uses as much as 900MB of ram (according to the apc.php charts). Just in case I have apc.shm_size set to 1600MB which is more than it needs but not more than I can spare. This means there is usually lots of extra RAM available to APC but also very little turnover and fragmentation is never more than 1%.

Is this dangerous? Should I be slimming down APC to less than 1GB just on principle? Should I be expecting some turnover within APC in the name of bringing it's overall footprint down?

Having so much memory devoted to APC means that in top/htop every single httpd process shows ~1.9GB in the VIRT memory column. Obviously this is shared memory and not used per-process, but could it be hurting our server?

NOTE: The problem with the server remains unclear but the effect is that about 60 times a day all 8 CPU's fill up to 100% and everything stops working until Monit sees that Apache is broken and restarts it (Monin also saves the MySQL server). I'm not sure if APC is even part of the problem but I'm trying to optimize everything just in case.


Having so much allocated is usually excessive. In this instance, you may feel you need to, because of all the different files. What may be more useful is to reduce the number of files that need to be cached by merging the Wordpress installs. In any event, if APC never reaches 1,000 MB used, having more than that is redundant.

How many MaxClients to set is a function of the busyness of the server, and particularly size of the resident portion of Apache and other programs. With 16GB of ram, even with say half of it allocated to Mysql (the InnoDB buffer pool - InnoDB controls member better than MyIsam, even at the cost of some more ram), a couple of hundred Apache processes is usually entirely enough (I was serving 10 million PHP hits per server per day and it averaged ~40 processes being used at a time).

Having the static images, css, JS etc served by NginX, sitting in front of (or on a seperate URL) the Apache server will also reduce the work that the heavier PHP-capable server is required to do - often very substantially. http://blogs.law.harvard.edu/djcp/2010/01/nginx-as-a-front-end-proxy-cache-for-wordpress/ has some thoughts on that, and there are other blogs and such that will walk you through installing Nginx in front of Apache, with or without Wordpress being involved.

Finally, KeepAlives will mainly just kill a busy site. Turning them off is recommended now, to avoid just the sort of resource starvation you are seeing regularly. If, for example, you have set 100 MaxClients, and a KeepAlive of 30 seconds, than just 100 visitors within a 30 sec period would hold open all the Apache slots, and you can't serve anything else. KeepAlive Off.

  • Thanks for the detailed reply! I'm already using Amazon s3 for most static files and am investigating but afraid of NginX, it will probably be my next big project. Keepalive is 2s which probably isn't the problem. – jerclarke Feb 28 '11 at 19:59

I don't think allocating that much memory is a problem if it's available and not needed elsewhere. One thing you could do is make better use of APC is to use a WordPress object cache like W3 Total Cache or Mark Jaquith's APC Object Cache Plugin.

For your CPU problem I would look at your MaxClients and MaxRequestsPerChild. They could be set too high. Also look at your KeepAliveTimeout setting and make sure it's not to high.

  • Thanks! Good ideas though I'm already running jaquith's plugin for the wp object cache system and added my most expensive and non-dynamic-needing queries to the object cache (and am running wp-supercache). I'm always trying to tweak the maxclients/maxrequestsperchild settings, though they don't seem to have much effect when the crashing-scenario occurs, the number of processes is always way lower than them and I have lots of extra RAM available. Keepalivetimeout is set to 2 seconds which seems like it should be safe. The problem is db queries that last for >30s and cause apache to freak out. – jerclarke Feb 28 '11 at 19:57
  • Check out W3 Total Cache as a replacement for the other 2 caching plugins. It gives you more control of the object cache and also has database caching. I run page, database and object cache through APC with w3 Total along with Nginx reverse proxy. I wrote a blog post on how to set up Nginx with WP and Apache, wp-performance.com/2010/10/… – Chris_O Feb 28 '11 at 20:41
  • If the DB queries are running that long, improve the database. Give it more memory (for MyIsam tables, at least as much ram as you have indexes), or better mostly or all into innoDB table-type and then as much space to the innodb-buffer-pool. Check other answers for DB optimisation. – Alister Bulman Feb 28 '11 at 20:44

I think you can allow as much memory as you want to APC. The memory used by APC to cache opcode will not be used by filesystem to cache files read.

To reduce CPU load you can configure expire on the assets (css, js, images). Install mod_expire on apache and use .htaccess to define expire header as you need. If you don't do this. The browsers check if files have changed even it has them in cache. This generate a lot of hits and drain CPU cycles.

Using les instance of wordpress would be nice too.

But the best increase would be to check how the wordpress site are coded. Plugins require lot of power. Sometime users install them for stupid things like including the Google Analytics code in the footer whereas it could be embbed in the footer.php template file.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.