More often than we thought we’re receiving inquiries from clients regarding a Magento deployment that is not performing to the level they expected. In this business the responsiveness of a client’s website is extremely important. If the browsing experience is lousy potential customers are going to move on to a competitor.
The single most effective configuration item for enhancing the performance of Magento is money – Crucial Hosting
If the site is intolerably slow potential shoppers will go back to the Google and pick the next vendor in the list for the product they are looking for. Typically, clients with the most challenging of these performance issues clients end up contacting the team Hybrid Global Inc. for an assessment and a resolution. Since the Magento eCommerce platform is based on the MVC brilliance of the Zend Framework we know that its extremely flexible and powerful. However, with great power comes great responsibilities. In the rush to re-platform an existing eCommerce package such as ZenCart, osCommerce, AspDotNetStoreFront, etc to Magento we’ve seen some absolutely tragic hacks of this framework.
Some of the more disconcerting examples are modified files in the /app/code/core (broken upgrade), completely copied default design directories with only one or two modified files and modifications pinned to specific database version (pre-1.2.1). Let’s get this straight – the learning curve is steep and perilous and you’ll get what you pay for if you choose a firm with little verifiable experience. While assessing and resolving these challenges is good for our business I think we all agree the world be would be a better place if we could avoid Magento missteps in the first place. The work isn’t done when the software is launched either. There are a number of logging tables that will grow unchecked less you perform regular maintenance on the database. The latest culprit we encountered in a recent audit is the “report_event” table. This particular Magento deployment had been running for a few months and collected well over a 150,000 records in the “report_event” table. By truncating this table we immediately realized a 500% improvement in php page execution time. Let me say that again, by truncating this single table we reduced page load time by 5X!
The recent Magento Enterprise Whitepaper contains some very useful configuration insight. If you haven’t read it yet download the Magento Enterprise Edition Whitepaper on Methods and Best Practices for High Performance eCommerce today.
The processes Hybrid Global Inc. has developed for deploying, maintaining and evaluating Magento installations is constantly evolving because Hybrid Global Inc. subscribes to a philosophy of continuous improvement. However, there many common elements to each and every deployment and this post serves as a abridged guide to some of the key technical elements gathered from both personal experience as well as fellow Magento authorities.
Abridged Magento Linux Installation and Optimization
We tend to deploy Magento on Centos 5.3 running Apache 2.2.x, PHP 5.2.x and Mysql 5.x. One of the first tricks is that PHP 5.2 is not available in the standard yum repositories. In order to install PHP 5.2 you’ll need to download and install the remi repositories via rpm:
1 wget <a href="http://download.fedora.redhat.com/pub/epel/5/i386/" target="_blank">http://download.fedora.redhat.com/pub/epel/5/i386/</a> epel-release-5-3.noarch.rpm
2 wget <a href="http://rpms.famillecollet.com/el5.i386/" target="_blank">http://rpms.famillecollet.com/el5.i386/</a> remi-release-5-7.el5.remi.noarch.rpm
3 rpm -Uvh remi-release-5*.rpm epel-release-5*.rpm
Now download PHP 5.2 – don’t get tempted by the 5.3.x release of PHP. Magento, as of this post is not compatible with PHP 5.3 so save yourself the grief of rolling back the PHP version and just say no (for now).
1 yum –enablerepo=remi install php-common-5.2.10-1.el5.remi
2 yum —enablerepo=remi install php-5.2.10-1.el5.remi
3 yum install gd gd-devel
4 yum –enablerepo=remi install php-mcrypt-5.2.10-1.el5.remi
5 php-xml-5.2.10-1.el5.remi php-devel-5.2.10-1.el5.remi
6 php-imap-5.2.10-1.el5.remi php-soap-5.2.10-1.el5.remi
7 php-mbstring-5.2.10-1.el5.remi php-mysql-5.2.10-1.el5.remi
8 yum –enablerepo=remi install php-mhash-5.2.10-1.el5.remi
9 php-gd-5.2.10-1.el5.remi
Install APC (Alternative PHP Cache)
1 yum –enablerepo=remi install php-pear php-devel-5.2.10-1.el5.remi httpd-devel
2 pear install pecl/apc
3 echo extension=apc.so > /etc/php.d/apc.ini
Now open the /etc/php.d/apc.ini and consider adding the following:
1 apc.enabled = 1
2 apc.shm_size = 128
3 apc.include_once_override = 1
4 apc.mmap_file_mask = /tmp/apc.XXXXXX
One more setting to consider and that’s:
1 apc.stat = 0
If stat is disabled APC will NOT check for updated versions of PHP files automatically. Apache must be restarted to check for PHP file changes. It is useful in production servers where PHP code is not changed frequently and offers an increase in performance.
Apache Configuration
The Mozilla Firefox Firebug Net tab and the add-on Y-Slow will reveal if apache is configured to both compress files and send expiry details to visiting browsers.
Enable Apache Content Expiration
Locate your httpd.conf and adding the following section. Feel free to modify the expiration lengths if that’s not consistent with your front-end update strategy. Pay particular attention to the .css file expiration.
1 <IfModule mod_expires.c>
2 ExpiresActive on
3 ExpiresByType image/gif “access plus 1 month”
4 ExpiresByType image/jpeg “access plus 1 month”
5 ExpiresByType image/jpg “access plus 1 month”
6 ExpiresByType image/png “access plus 1 month”
7 ExpiresByType text/plain “access plus 15 day”
8 ExpiresByType text/html “access plus 1 second”
9 ExpiresByType text/css “access plus 1 day”
10 ExpiresByType text/javascript “access plus 1 day”
11 ExpiresByType application/x-shockwave-flash “access plus 1 day”
12 ExpiresByType application/x-httpd-php “access plus 1 second”
13 </IfModule>
Enable Apache Output Compression
1 <IfModule mod_deflate.c>
2 AddOutputFilterByType DEFLATE text/html
3 AddOutputFilterByType DEFLATE text/plain
4 <FilesMatch “\.(js|css)$”>
5 SetOutputFilter DEFLATE
6 </FilesMatch>
7 </IfModule>
After changes are made to the apache configuration you’ll of course need to restart the apache daemon.
MySQL Configuration
Open the /etc/my.cnf file and review the cache settings for MySQL. In a well spec’d server hosting a product catalog of up to 10,000 products these settings are a good rule of thumb. Magento uses Innodb type tables so the size of the innodb_buffer_pool_size is highly correlated to improved performance.
1 query_cache_type = 1
2 query_cache_size = 64M
3 innodb_buffer_pool_size = 256M
4 thread_cache_size = 16
5 table_cache = 512
6 key_buffer = 32M
.htaccess
Along with the standard Magento rewrite conditions avoid duplicate content issues by redirecting non-www requests to the www.mydomain.com.
1 RewriteCond %{HTTP_HOST} ^mydomain.com [NC]
2 RewriteRule ^(.*)$ <a href="http://www.mydomain.com/" target="_blank">http://www.mydomain.com/</a>$1 [L,R=301]
File permissions
Reset your file permissions by running the following commands in the root of the Magento installation:
1 find . -type f -exec chmod 644 {} \;
2 find . -type d -exec chmod 755 {} \;
3 chmod o+w var var/.htaccess includes includes/config.php app/etc
4 chmod 550 pear
5 chmod -R o+w media
In order run Magento Connect you may need to TEMPORARILY loosen file permissions by executing these commands in the root of the Magento installation:
1 find . -type d -exec chmod 777 {} \;
2 find . -type f -exec chmod 644 {} \;
Clean Up Script
Download the Magento Cleanup Tool and schedule its execution. I wouldn’t recommend exposing it to the world as suggested in the Magento Wiki page however.
http://www.magentocommerce.com/wiki/groups/227/resetting_file_permissions
References for this Post
Do it your-selfers will appreciate the single best, almost biblical, reference for Magento server setup and optimization is the Crucial Web Hosting blog at http://www.crucialwebhost.com/blog/magento-commerce-install-guide/