Rupert Jones

Following our earlier entry about installing Magento Enterprise, we thought it would be appropriate to follow up with some tips for getting more from your Magento installation. One of the major criticisms leveled at Magento is its speed; many complain that it is far too slow. In this article we'll go through some steps you can perform to fine-tune your server to allow Magento to run more smoothly and more quickly in a production environment. Our examples are geared at a Debian-based LAMP stack, but most can be adapted for other platforms.

Check out our tips on:



Memcached

Memcached is a distributed memory caching system that stores data retrieved from the database (or other data source) in memory, allowing repeat reads to retrieve the data from memory rather than needing to query the database again, greatly increasing the speed of web applications.

The first thing to do is install the memcache daemon and client libraries:

root# apt-get update
root# apt-get install memcached php5-memcache

To check if memcache is running, you can use the following command:

root# ps -ef | grep memcached

You should ensure that the localhost has been added to the configuration, this can be done using grep as shown here:

root# grep 127.0.0.1 /etc/memcached.conf

This should output -l 127.0.0.1 if localhost is included in the configuration. If not, add this line to the configuration and restart memcached:

root# echo '-l 127.0.0.1' >> /etc/memcached.conf
root# /etc/init.d/memcached restart
root# /etc/init.d/apache2 restart

You need to create a PHP configuration file to include the module, which on a Debian-based system should be in /etc/php5/conf.d/memcache.ini:

extension=memcache.so

Magento itself can also be configured to utilise some memcache optimisations built into the software. The following XML should be added to the /var/www/app/etc/local.xml file once it has been generated:

 <config>
     <global>
         ...
         <cache>
             <backend><![CDATA[memcached]]></backend><!-- apc / memcached / xcache / empty=file -->
             <slow_backend><![CDATA[database]]></slow_backend>
             <memcached><!-- memcached cache backend related config -->
                 <servers><!-- any number of server nodes can be included -->
                     <server>
                         <host><![CDATA[127.0.0.1]]></host>
                         <port><![CDATA[11211]]></port>
                         <persistent><![CDATA[1]]></persistent>
                         <weight><![CDATA[1]]></weight>
                         <timeout><![CDATA[10]]></timeout>
                         <retry_interval><![CDATA[10]]></retry_interval>
                         <status><![CDATA[1]]></status>
                     </server>
                 </servers>
                 <compression><![CDATA[0]]></compression>
                 <cache_dir><![CDATA[]]></cache_dir>
                 <hashed_directory_level><![CDATA[]]></hashed_directory_level>
                 <hashed_directory_umask><![CDATA[]]></hashed_directory_umask>
                 <file_name_prefix><![CDATA[]]></file_name_prefix>
             </memcached>
         </cache>
     </global>
     ...
 </config>


Apache mod_cache

The Apache mod_cache module allows Apache to cache content on disk or in memory, thus decreasing page load times. Caching for dynamic sites such as ecommerce needs to be approached with some caution; the cache may become invalid and thus customers may receive stale content. To enable mod_cache perform the following steps:

root# a2enmod cache
root# a2enmod disk_cache
root# a2enmod mem_cache

Enable disk caching in the disk_cache.conf configuration file by uncommenting the CacheEnable line in /etc/apache2/mods-available/disk_cache.conf. Make sure you remember to restart apache after doing this.

There is also a utility you can install which will clear the disk cache, the following code sample shows how to install and run it:

root# apt-get install apache2-utils
root# htcacheclean -d30 -n -t -p /var/cache/apache2/mod_disk_cache -l 100M -i

This will clean our cache directory every 30 minutes and make sure that it will not get bigger than 100MB. You can tune these settings to fit your particular site needs.


Apache mod_expires

Well-written browser software will keep a cache of the webpages a user visits. Each webpage should have a content expiry header directive that tells the browser when the cache expires. If this header is not correctly set then the browser will re-request the content from source with every page hit. In order to ensure that the Magento pages have the correct content expiry in the header, you can add the following block to Magento's .htaccess file:

<ifmodule mod_expires.c>
    ExpiresActive On
    ExpiresDefault "access plus 1 month"
</ifmodule>


Apache KeepAlive

The Apache KeepAlive functionality allows the TCP connection between a client and the server to remain open, allowing multiple requests to be served over the same connection. This can decrease page load times particularly on webpages with lots of images since it removes the overhead of having multiple connections opened. To use this functionality, edit the /etc/apache2/apache2.conf, find the KeepAlive entries, and make sure they are enabled as follows:

KeepAlive On
KeepAliveTimeout 2

This will enable the KeepAlive feature; the timeout parameter is in units of seconds.


PHP APC

PHP APC is an Alternative PHP Cache that caches the byte-compiled PHP code, which means that repeat requests to the same PHP script should not need to be recompiled before being served, which will increase performance. This is a pear module, but also has some system dependencies, so to install it we run the following:

root# apt-get install apache2-threaded-dev php5-dev php-pear make gpp
root# pecl install apc

The APC configuration file should be created, and on the debian system the path would be /etc/php5/conf.d/apc.ini. We place the following lines into this file:

extension=apc.so
apc.shm_size=256
apc.num_files_hint=10000
apc.user_entries_hint=10000
apc.max_file_size=5M

Also make sure that Magento is using APC for caching by editing /var/www/app/etc/local.xml and add the following somewhere inside the <global> tags:

<config>
        <global><cache>
                        <backend>apc</backend>
                        <prefix>alphanumeric</prefix>
                </cache>
                ….
        </global>
        ...
</config>

To verify if APC is installed, we can check if the output of phpinfo includes reference to it, by running the following command from the CLI:

root# php -r 'phpinfo();' | grep 'apc'


Database Session Storage

Typically, database servers are less utilised than web servers. Performance can usually be improved by moving session handling from the web server filesystem into the database server. Magento asks you whether you prefer a file or database session save type, but this is very easy to change in the XML. Open up /var/www/app/etc/local.xml, locate the <session_save> tags, and change the value so it looks like this (the default is <![CDATA[files]]>):

<session_save><![CDATA[db]]></session_save>

Another alternative is to use memcache for storing the sessions - this isn’t as persistent as the database store, but may be faster:

<session_save><![CDATA[memcache]]></session_save>

You can add details of your memcache server in the session save path:

<session_save_path><![CDATA[tcp://127.0.0.1:11211?persistent=1&weight;=2&timeout;=10&retry;_interval=10]]></session_save_path>


GZip Compression

Web pages can be compressed using GZip between the server and the client, reducing the amount of data that needs to be transferred. Although the act of compressing and decompressing adds a performance overhead there is usually a net gain in reducing the amount of traffic especially for large pages. To use GZip compression, enable the mod_deflate module in Apache, and add the following to the vhost for the site:

<ifmodule mod_deflate.c>
        SetOutputFilter DEFLATE
        # Netscape 4.x has some problems...
        BrowserMatch ^Mozilla/4 gzip-only-text/html
        # Netscape 4.06-4.08 have some more problems
        BrowserMatch ^Mozilla/4.0[678] no-gzip
        # MSIE masquerades as Netscape, but it is fine
        BrowserMatch bMSIE !no-gzip !gzip-only-text/html
        # Don't compress images
        SetEnvIfNoCase Request_URI .(?:gif|jpe?g|png)$ no-gzip dont-vary
        # Make sure proxies don't deliver the wrong content
        Header append Vary User-Agent env=!dont-vary
</ifmodule>


MySQLTuner

A final tool to consider for performance improvement is MySQLTuner. MySQLTuner is a Perl script which analyses your database and gives recommendations which variables you should adjust in my.cnf to increase performance. This can really help to get the database, often a performance bottleneck for these types of applications, performing as well as possible without needing expensive hardware upgrades. To install and run this utility, simply do:

bash$ wget http://mysqltuner.com/mysqltuner.pl
bash$ perl mysqltuner.pl

You see some recommendations for which variables could be changed to improve performance, it is best to make changes incrementally and one at a time so you can see how they affect the performance of the database


Bonus Security Tip: Changing the Admin URL

Although not an actual performance issue, you can improve security by changing the default URL from 'admin' to something more obscure, such as '5i8FNvHg'. This will decrease the probability that a malicious user will hit upon your admin log-in page by guessing that the admin site is located at yourdomain.com/admin/, or that automated scripts scanning for Magento admin pages will find it.
To change the admin address you first need to stop Apache and clear the cache:

root# /etc/init.d/apache2 stop
root# rm -rf /var/www/var/cache/*
root# rm -rf /var/www/var/session/*

Then open up the /var/www/app/etc/local.xml file, locate the <frontName> tag, and change the 'admin' part it to something a lot more random, eg:

              <frontName><![CDATA[gJpf2VK5]]></frontName>

Then set Apache running again (bearing in mind your site will be down for the duration of this operation!):

root# /etc/init.d/apache2 start

More Tips?

This was a selection of the tips we use to keep our Magento sites running smoothly; but is there anything we missed? If you have comments or tips for other users, please leave us a comment and let us know!

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Plus

13 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. How does mod_cache compare to a dedicated cache such as varnish in terms of performance, ease of use, etc.? Despite being integrated into Apache, I never really hear people mention it, which leads me to think that it's not very widely used. I guess the market for cache on a one server solution is not all that large...

  2. Tero said

    Same performance improvements can be done other web softwares too and this doesn't change that Magento is poorly designed and over engineered software. Many softwares compare better when same steps are done.

  3. I would suggest that, if you're using Memcache to store Magento data, you might as well use it to store sessions. It will avoid 2 database queries (1 select, 1 update) per hit.
    Worst thing that can happen is when you have multiple Memcache servers and one of them crashes. All sessions stored on that server will be lost. So keep that in mind. If you're running it all on 1 machine, you might as well do that, otherwise look at Membase or the repcached solution

  4. I have to agree with Tero that these changes can be made to any system to make it faster. In fact, other then the memcached section, these 'optimisations' apply to all php code, without having to change anything about the code. (Memcached can also always be used, but needs to be supported by the application - and it is nice that Magento does that out of the box.)

    You're running both APC and Memcache on your webserver, did you consider using APC to also cache userdata? (Making Memcache obsolete.)

    Final question: Did the work pay off? Do you now have a snappy, 'loads right away', 'never have to wait' webshop, or is it still not all that great?

  5. Very nice tips on optimizing Magento performance. Apart from those store owners should also think about:

    1. Magento Compiler
    2. Disabling unused Magento modules
    3. Compress PHP output
    4. Minify JavaScript and CSS files
    5. Store dynamic data on memory-based file-systems – use tmpfs or RAMdisk to store va/cache or var/session

    I think there are numerous other options as well but if the basics are covered then they won't complain Magento being so slow.

  6. Tim Schliter said

    Hi Rupert,
    thanks for your tips, some of these are very useful.

    I can also recommend this blog post:
    http://mgt-commerce.com/blog/magento-on-steroids-best-practice-for-highest-performance/

Continuing the Discussion

  1. Optimising Magento for Performance – techPortal | Magento News linked to this post on March 8, 2011

    [...] Optimising Magento for Performance – techPortal [...]

  2. Ibuildings techPortal: Optimising Magento for Performance | Development Blog With Code Updates : Developercast.com linked to this post on March 8, 2011

    [...] techPortal today there’s a new tutorial from Rupert Jones showing you how to get the best performance from Magento with a set of technologies tailored for just that. Following our earlier entry about installing [...]

  3. abcphp.com linked to this post on March 9, 2011

    Optimising Magento for Performance...

    Web performance tips aimed specifically at getting the best out of a Magento platform. Magento is notoriously slow and does not scale well - this article gives you some tips to try before you upgrade your hardware....

  4. Ibuildings techPortal: Optimising Magento for Performance | Scripting4You Blog linked to this post on March 10, 2011

    [...] techPortal today there’s a new tutorial from Rupert Jones showing you how to get the best performance from Magento with a set of technologies tailored for just that. Following our earlier entry about installing [...]

  5. A semana no mundo PHP (11/03/2011) | raphael.dealmeida linked to this post on March 11, 2011

    [...] Optimising Magento for Performance – techPortal [...]

Some HTML is OK

(required)

(required, but never shared)

or, reply to this post via trackback.