APC and Memcache with Magento

You need to understand the clear distinction between these two products to understand how to use them.

  • APC is both an OPCode Cache and Fast Backend
  • Memcache is just a Fast Backend

Using APC as an OPCode Cache

Simply install the module on your server

pecl install apc

And enable it in your php.ini

echo "extension=apc.so" >> /usr/lib/local/php.ini       (RedHat/Centos)
echo "extension=apc.so" >> /etc/php5/conf.d/20apc.ini   (Debian)

You then enable and fine-tune the runtime configuration to suit, eg.

apc.enabled
apc.shm_segments
apc.shm_size
apc.optimization
apc.num_files_hint
apc.user_entries_hint
apc.ttl
apc.user_ttl
...

Then restart PHP/Apache

/etc/init.d/httpd restart                               (RedHat/Centos)
/etc/init.d/apache2 restart                             (Debian)

After that, there is nothing else to do. Confirm APC is enabled with a quick phpinfo() - but otherwise, at this point, the OPCode cache portion of APC is active.

Nothing needs to be configured on Magento's side.

Using APC as a Fast Backend

You need to add the following to your ./app/etc/local.xml

<global>
  ...
  <cache>
    <backend>apc</backend>
      <prefix>mystore_</prefix>
  </cache>
  ...
</global>

Then flush your existing store caches. To verify it is working, load a page in the front-end and the ./var/cache directory should remain empty.

Using Memcache as a Fast Backend

You'll need to install Memcache as a PHP extension, and install the respective Memcache Daemon (Memcached) on your server.

pecl install memcache

And enable it in your php.ini

echo "extension=memcache.so" >> /usr/lib/local/php.ini            (RedHat/Centos)
echo "extension=memcache.so" >> /etc/php5/conf.d/20memcache.ini   (Debian)

/etc/init.d/httpd restart                               (RedHat/Centos)
/etc/init.d/apache2 restart                             (Debian)

Then install Memcached on the server. For RH/Centos, adjust the URL to suit your release version and CPU architecture.

rpm -Uhv https://apt.sw.be/redhat/el6/en/x86_64/rpmforge/RPMS/rpmforge-release-0.5.2-2.el6.rf.x86_64.rpm
yum --enablerepo=rpmforge install memcached

apt-get install memcached                               (Debian)

Then modify Magento to use Memcache as a fast backend, change the socket path to a TCP/IP connection to suit.

<cache>
  <slow_backend>database</slow_backend>

  <fast_backend>memcached</fast_backend>
  <fast_backend_options>
    <servers>
      <server>
        <host>unix:///tmp/memcached.sock</host>
        <port>0</port>
        <persistent>0</persistent>
      </server>
    </servers>
  </fast_backend_options>

  <backend>memcached</backend>
  <memcached>
  <servers>
    <server>
      <host>unix:///tmp/memcached.sock</host>
      <port>0</port>
      <persistent>0</persistent>
    </server>
  </servers>
</cache>

The caveats of Memcache and tagging - what is it storing

Memcache only supports a single level of key-value relationships, so it cannot store the Magento cache tags (that are used to flush cache data independently). As a result, you either need to specify a slow_backend to maintain the cache content tag relationship, or don't define one at all.

If you define a slow_backend, you run the risk of the cache tags growing so large that performance is negated; there is also the inherent problem that you cannot scale across multiple servers if each server is maintaining their own cache tags.

So when using Memcache, the better approach (with the caveat you cannot flush caches independently), is to not bother using the slow_backend.

In which case, we suggest removing <slow_backend>database</slow_backend> and replacing it with:

  <slow_backend>Memcached</slow_backend>
  <slow_backend_options>
    <servers>
      <server>
        <host>unix:///tmp/memcached.sock</host>
        <port>0</port>
        <persistent>0</persistent>
      </server>
    </servers>
  </slow_backend_options>

This will break/disable the 2nd level of caching (and prevent tag storage), but still allow the performance of Memcache.

Which to use

If its a single server deployment - there's no harm just using APC for everything.

If its a distributed set-up - then you'll need to use Memcache as the fast backend (so that all machines can access the common store).

What would we use?

Well, neither actually.

We use MageStack - which is an ultra high performance Magento Operating System that provides native operational code caching beyond that of APC (with a ~8% performance improvement), and utilises an advanced cache back-end that does support cache tagging.