Drupal site excessive memory usage traced to APC and php5-memcached

We were recently troubleshooting a client site running Drupal 7.x, and main complaint was high memory usage on all the site's pages.

We were able to diagnose and solve two main causes that range from the common to unusual.

This is a Drupal 7 Commerce site with 173 modules, and 3 themes enabled. Apache Solr is used for search, and there is custom code to talk over the network to a non-Drupal backend server.

The site runs on a Debian Squeeze Xen VPS.

For most of the site's pages, the client was seeing high memory usage, as follows:

Problem: high memory usage

When every page load has extremely excessive memory usage, this could be a bottleneck for the site scaling well, since the server has to have enough memory to cope with many pages at the same time using lots of memory.

The first access to a page, where APC has not yet cached anything, would look like this in devel:

Memory used at: devel_boot()=6.92 MB, devel_shutdown()=236.03 MB, PHP peak=243.25 MB.

Subsequent access would show less memory usage, since APC caches the Drupal PHP files, like so:

Memory used at: devel_boot()=6.54 MB, devel_shutdown()=174.37 MB, PHP peak=175.5 MB.

Some page even reported up to 192 MB of peak memory!

That is still excessive. For a site with that many modules, we expected that memory usage would be high, but not to that extent.

Solutions to high memory usage

Increasing APC shared memory size

First, the allocated shared memory for APC was not enough.

The apc.shm_size parameter for APC is set to the default of 32MB.

The code base with that many modules needed at least double that or more.

So, increasing this to 96MB, solved that part.

To do so on Debian or Ubuntu, change the following line in the file /etc/php5/apache2/conf.d/apc.ini

apc.shm_size = 96

Replacing php5-memcached with php-memcache

The other big cause of excessive memory usage was quite unusual. It was the use of php5-memcached (notice the "d") to connect PHP with the memcached daemon, rather than the more commonly used php5-memcache (without a "d").

For some unknown reason, the PHP memcached extension (from the Debian package php5-memcached) uses way more memory than the php5-memcache extension.

In order to remedy this, do the following:

$ sudo aptitude purge php5-memcached
$ sudo aptitude install php5-memcache

What a difference a "d" makes!

Results

The results after doing both of the above things were dramatic. Instead of 175 MB per page, it is now a more typical (for a complex site): 60 MB!

Memory used at: devel_boot()=2.15 MB, devel_shutdown()=58.4 MB, PHP peak=59.5 MB.

Note that these figures are not absolute, and will vary from distro to distro and server to server, depending on what modules you have enabled in PHP and Apache, and many other factors. What matters is the comparative figures, not absolute figures.

For example, the same site on an Ubuntu Server LTS 12.04, which we used for our lab servers:

Memory used at: devel_boot()=2.11 MB, devel_shutdown()=72.27 MB, PHP peak=75.75 MB.

It will be different on CentOS.

Contents: 

Tags: 

Comments

Trouble replicating

I tried to see if I could replicate this on an Ubuntu 12.04 VM and can't see any difference in memory use. This was on a fresh site install with lots of code, but little content. It makes me wonder if there's something in the Drupal Commerce stack that is triggering it. Also, was using the 7.x-1.0 release of the memcache Drupal module which could be related if you're on a different version.

Hmmm. Interesting ...

Interesting observation.

We verified it on Ubuntu 12.04 (dedicated server) as well as Debian Squeeze (Virtual Machine).

Can't see why Drupal Commerce, or anything else use php5-memcached or php5-memcache differently than other modules? It is all cache_set() and cache_get() after all.

I don't see any difference,

I don't see any difference, you can have both these PHP modules installed and choose what to use. Without optimizing the cache files, its just flaw to say one did better performance than other. For memcached you have to use extra initiative what database load does it caches. A bit of tweaking can give more performance, and to squeeze the performance, you need time and patience...

Nice article though, btw how I can RSS your articles ???

Not performance, memory usage

This article is not about performance of one configuration over the other. It is about excessive memory usage when one is used but not the other.

This was verified on both Debian and Ubuntu. Are you on CentOS?

You can subscribe to our Drupal performance articles via the Drupal Planet.

sorry didn't notice your

sorry didn't notice your blogs in Drupal Planet before

As you mentioned APC is also used and you have increased the memory allocation to APC, though enabling user cache in APC is one viable option IMO. I haven't performed the test myself about this memcache or memcached pecls, but memcached needs some configuration with external library also used. So, the issue might be memcached already installed but didn't serve any caches (just a guess). It would be interesting to learn from you, if you have already tested what memcached/memcache was serving.

I retired RHEL/CentOS long time ago, I use Ubuntu and FreeBSD these days.

Yes, there were two issues

Yes, there were two issues, but one alone did not solve the excessive memory usage issue.

Memcache was working fine, but pages were using too much memory with php5-memcached, and back to normal with php5-memcache.

Cannot see this change in PHP-fpm and ngnix environement

Thanks for the tip. I tried this on one of our sites uses Drupal commerce and it worked. The memory before increasing the apc.shm_size was 112M and after increasing the apc.shm_size it came down to 60M. The environemnet was apache2 with php module.

But when I tried to replicate this to our production server which is running ngnix with php-fpm, there is no significant change in the memory usage. It is still around 112M. Any clue on that?

Thanks

What is your Memory Limit setting set to?

I too have a large drupal 7 site with ubercart and has about 140 modules enabled.
My question is this...

On you site you have 173 modules installed. What is your memory limit on your settings file set to? I had it at 128 but i kept on getting white page out of memory errors. So had to increase it, I have just not found anybody to recommend a memory limit for a site with so many modules installed. What is your setting for this? I dont want to have it too high but have no idea how to get the correct setting for this.

Our logged in users are seeing a super slow page. Any tips to make their sessions faster?

Thank you for any feedback you can give.

Not modules alone ...

Number of modules is one important indicators. What these modules are and how they are use are other important factors. For example,

On a site with 210 modules, but also configured in a memory hogging way (lots of blocks are processed for each page), we had to increase memory_limit to 256MB to get over white screens.

So it all depends on how many modules are enabled, what these modules are, and how they are configured.

As for slowness it can be many things. The sure way to know why it happens is to perform a performance assessment.

Performance assesment?

And how does one do a performance assessment?

Thanks for the help and sorry for the newbie questions.

Performance Assessment

You do a performance assessment by a thorough investigation on what the performance issues are, what symptoms are present, what bottlenecks are out there, what their root cause(s) are, and devise solutions for each.

You can do this on your own with help from the Drupal knowledgebase spread around the internet (starting with the articles on this very site), or you can get us to do it for you. See our services section.

not an expert but it is working

I am not an expert but i had the exact problem, and I did the APC part and peak whent from 177MB to 50MB, but i do not understand what is that mean. but it is working :)