Your message has been sent.
This article has been saved to your account.
Go to my account
This article has been emailed to your Kindle.
Send this article
Complete the form below to send this article, How to Overcome the Pitfalls of Magento, to a friend (or to yourself). We will never share your details (or your friend's) with anyone. For more information, read our Privacy Policy.
In this article we will describe how to overcome some of the most common pitfalls that people encounter. For example, in Magento, backoffice is slow, frontend tends to die while loading, accessibility is far from perfect, an AJAX request is not successful due to expiration of the session, nothing happens, no error message, just nothing, the nightmare of XML layout, and so on.
In this article by Nurul Ferdous, author of Magento 1.4 Development Cookbook, we will cover:
- Using APC/Memcached as the cache backend
- Accelerating PHP: php.ini configuration
- Applying YSlow and Page Speed rules
| Read more about this book |
(For more resources on Magento, see here.)
The reader can benefit from the previous article on Magento 1.4: Performance Optimization.
Using APC/Memcached as the cache backend
Magento has got a cache system that is based on files by default. We can boost the overall performance by changing the cache handler to a better engine like APC or Memcached. This recipe will help us to set up APC or Memcached as the cache backend.
Getting ready
Installation of APC:
Alternative PHP Cache (APC) is a PECL extension. For any Debian-based Distro, it can be installed with an easy command from the terminal:
sudo apt-get install php5-apc
Or:
sudo pecl install APC
You can also install it from the source. The package download location for APC is: http://pecl.php.net/package/APC. Check whether it exists or not in phpinfo(). If you cannot see an APC block there, then you might not have added APC in the php.ini file.
Installation of Memcached:
Memcached is also available in most OS package repositories. You can install it from the command line:
sudo apt-get install php5-memcached
Memcached could be installed from source as well. Check whether it exists or not in phpinfo(). If you cannot see a Memcached block there, then you might not have added Memcached in the php.ini file.
You can also check it via the telnet client. Issue the following command in the terminal:
telnet localhost 11211
We can issue the get command now:
get greeting
Nothing happened? We have to set it first.
set greeting 1 0 11
Hello World
STORED
get greeting
Hello World
END
quit
How to do it...
- Okay, we are all set to go for the APC or Memcached. Let's do it now for APC. Open local.xml in your favorite PHP editor. Add the cache block as follows:
<?xml version="1.0"?>
<config>
<global>
<install>
<date><![CDATA[Sat, 26 Jun 2010 11:55:18 +0000]]></date>
</install>
<cache>
<backend>apc</backend>
<prefix>alphanumeric</prefix>
</cache>
<crypt>
<key><![CDATA[870f60e1ba58fd34dbf730bfa8c9c152]]></key>
</crypt>
<disable_local_modules>false</disable_local_modules>
<resources>
<db>
<table_prefix><![CDATA[]]></table_prefix>
</db>
<default_setup>
<connection>
<host><![CDATA[localhost]]></host>
<username><![CDATA[root]]></username>
<password><![CDATA[f]]></password>
<dbname><![CDATA[magento]]></dbname>
<active>1</active>
</connection>
</default_setup>
</resources>
<session_save><![CDATA[files]]></session_save>
</global>
<admin>
<routers>
<adminhtml>
<args>
<frontName><![CDATA[backend]]></frontName>
</args>
</adminhtml>
</routers>
</admin>
</config> - Delete all files from the var/cache/ directory. Reload your Magento and benchmark it now to see the boost in performance. Run the benchmark several times to get an accurate result.
ab -c 5 -n 100 http://magento.local.com/
- You can use either APC or Memcached. Let's test it with Memcached now. Delete the cache block as we set with APC previously and add the cache block as follows:
<?xml version="1.0"?>
<config>
<global>
<install>
<date><![CDATA[Sat, 26 Jun 2010 11:55:18 +0000]]></date>
</install>
<crypt>
<key><![CDATA[870f60e1ba58fd34dbf730bfa8c9c152]]></key>
</crypt>
<disable_local_modules>false</disable_local_modules>
<resources>
<db>
<table_prefix><![CDATA[]]></table_prefix>
</db>
<default_setup>
<connection>
<host><![CDATA[localhost]]></host>
<username><![CDATA[root]]></username>
<password><![CDATA[f]]></password>
<dbname><![CDATA[magento]]></dbname>
<active>1</active>
</connection>
</default_setup>
</resources>
<session_save><![CDATA[files]]></session_save>
<cache>
<backend>memcached</backend> apc / memcached / xcache /
empty=file
<slow_backend>file</slow_backend> database / file (default)
- used for 2 levels cache setup, necessary for all shared memory
storages
<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[2]]></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>
<admin>
<routers>
<adminhtml>
<args>
<frontName><![CDATA[backend]]></frontName>
</args>
</adminhtml>
</routers>
</admin>
</config> - Save the local.xml file, clear all cache files from /var/cache/ and reload your Magento in the frontend and check the performance.
- Mount var/cache as TMPFS:
mount tmpfs /path/to/your/magento/var/cache -t tmpfs -o size=64m
How it works...
Alternative PHP Cache (APC) is a free, open source opcode cache framework that optimizes PHP intermediate code and caches data and compiled code from the PHP bytecode compiler in shared memory, which is similar to Memcached. APC is quickly becoming the de facto standard PHP caching mechanism, as it will be included built-in to the core of PHP, starting with PHP 6. The biggest problem with APC is that you can only access the local APC cache.
Memcached's magic lies in its two-stage hash approach. It behaves as though it were a giant hash table, looking up key = value pairs. Give it a key, and set or get some arbitrary data. When doing a memcached lookup, first the client hashes the key against the whole list of servers. Once it has chosen a server, the client then sends its request, and the server does an internal hash key lookup for the actual item data. Memcached affords us endless possibilities (query caching, content caching, session storage) and great flexibility. It's an excellent option for increasing performance and scalability on any website without requiring a lot of additional resources.
Changing the var/cache to TMPFS is a very good trick to increase disk I/O. I personally found both APC's and Memcached's performance pretty similar. Both are good to go. If you want to split your cache in multiple servers go for the Memcached. Good Luck!
The highlighted sections in code are for the APC and Memcached settings, respectively.
| Read more about this book |
(For more resources on Magento, see here.)
Accelerating PHP: php.ini configuration
If you don't use an APC-like accelerator, then it's time to use one. As, when a PHP script is requested, PHP reads the script and compiles it into what's called Zend opcode, a binary representation of the code to be executed. This opcode is then executed by the PHP engine and thrown away. An opcode cache saves this compiled opcode and reuses it the next time the page is called. This saves a considerable amount of time. In this recipe, we will learn how to optimize the php.ini configuration for its best performance.
Getting ready
There are many PHP accelerators out there. You can go for any of them. Such as APC, eAceelerator, XCache, Zend Accelerator (a tool in Zend server), Zend Platform, and so on. Here are some URLs for your convenience:
- APC: http://pecl.php.net/package/APC
- EAccelerator: http://eaccelerator.net/
- XCache: http://xcache.lighttpd.net/
How to do it...
- The very first job is to use an efficient process manager such as php-fpm, which runs FastCGI with impressive speed.
- Use realpath_cache_size in php.ini. This denotes the size of the realpath cache to be used by PHP. This value should be increased on systems where PHP opens many files, to reflect the quantity of the file operations performed. Here is mine:
realpath_cache_size=1M
realpath_cache_ttl=86400 - There are some other resources as well, which can improve the overall performance:

- Last but not the least is to set error reporting to off.
How it works...
These numbers depend mostly on your application. If you accept large files from users, then max_input_time may have to be increased, either in php.ini or by overriding it in code. Similarly, a CPU- or memory-heavy program may need larger settings. The purpose is to mitigate the effect of a runaway program, so disabling these settings globally isn't recommended. Another note on max_execution_time: This refers to the CPU time of the process, not the absolute time. Thus, a program that does lots of I/O and few calculations may run for much longer than max_execution_time. It's also how max_input_time can be greater than max_execution_time.
The amount of logging that PHP can do is configurable. In a production environment, disabling all but the most critical logs saves disk writes. If logs are needed to troubleshoot a problem, you can turn up logging as needed. error_reporting = E_COMPILE_ERRORE_ERROR|E_CORE_ERROR| turns on enough logging to spot problems but eliminates a lot of chatter from scripts.
Applying YSlow and Page Speed rules
YSlow and Page Speed both are very useful, FREE tools for optimization experts. Personally, I use both of them. Both have some defined rulesets and options to create on your own by modifying a ruleset. This recipe will let us apply those rules in our application.
Getting ready
We must have installed the Firefox browser and the following add-ons to work with this recipe. Make sure these tools are installed and regarding versions, the later the better.

How to do it...
YSlow analyzes a web page on a selected ruleset, Ruleset YSlow(v2) and Ruleset YSlow(v1). v2 comprised 22 rules while v1 has 13 rules. We will be using v2, which has the following rules. Studies have shown that web page response time can be improved by 25 percent to 50 percent by following these rules:
- Minimize HTTP requests
- Use a content delivery network
- Add an expires or a cache-control header
- Gzip components
- Put StyleSheets at the top
- Put scripts at the bottom
- Avoid CSS expressions
- Make JavaScript and CSS external
- Reduce DNS lookups
- Minify JavaScript and CSS
- Avoid redirects
- Remove duplicate scripts
- Configure ETags
- Make AJAX cacheable
- Use GET for AJAX requests
- Reduce the number of DOM elements
- No 404s
- Reduce cookie size
- Use cookie-free domains for components
- Avoid filters
- Do not scale images in HTML
- Make favicon.ico small and cacheable
- At this stage, if we run the YSlow test then we should see the overall grade is B. We failed at "use a content delivery network (CDN)". For convenience, I am attaching the full and final .htaccess file here:
############################################
## uncomment these lines for CGI mode
## make sure to specify the correct cgi php binary file name
## it might be /cgi-bin/php-cgi
# Action php5-cgi /cgi-bin/php5-cgi
# AddHandler php5-cgi .php
############################################
## GoDaddy specific options
# Options -MultiViews
## you might also need to add this line to php.ini
## cgi.fix_pathinfo = 1
## if it still doesn't work, rename php.ini to php5.ini
############################################
## this line is specific for 1and1 hosting
#AddType x-mapp-php5 .php
#AddHandler x-mapp-php5 .php
############################################
## default index file
DirectoryIndex index.php
<IfModule mod_php5.c>
############################################
## adjust memory limit
# php_value memory_limit 64M
php_value memory_limit 128M
php_value max_execution_time 18000
############################################
## disable magic quotes for php request vars
php_flag magic_quotes_gpc off
############################################
## disable automatic session start
## before autoload was initialized
php_flag session.auto_start off
############################################
## enable resulting html compression
php_flag zlib.output_compression on
###########################################
# disable user agent verification to not break multiple image
upload
php_flag suhosin.session.cryptua off
###########################################
# turn off compatibility with PHP4 when dealing with objects
php_flag zend.ze1_compatibility_mode Off
</IfModule>
<IfModule mod_security.c>
###########################################
# disable POST processing to not break multiple image upload
SecFilterEngine Off
SecFilterScanPOST Off
</IfModule>
<IfModule mod_deflate.c>
############################################
## enable apache served files compression
##http://developer.yahoo.com/performance/rules.html#gzip
# Insert filter on all content
SetOutputFilter DEFLATE
# Insert filter on selected content types only
AddOutputFilterByType DEFLATE text/html text/plain text/xml
text/css text/javascript
# 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 dontvary
# Make sure proxies don't deliver the wrong content
Header append Vary User-Agent env=!dont-vary
</IfModule>
<IfModule mod_ssl.c>
############################################
## make HTTPS env vars available for CGI mode
SSLOptions StdEnvVars
</IfModule>
<IfModule mod_rewrite.c>
############################################
## enable rewrites
Options +FollowSymLinks
RewriteEngine on
############################################
## you can put here your magento root folder
## path relative to web root
#RewriteBase /magento/
############################################
## workaround for HTTP authorization
## in CGI environment
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
############################################
## always send 404 on missing files in these folders
RewriteCond %{REQUEST_URI} !^/(media|skin|js)/
############################################
## never rewrite for existing files, directories and links
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
############################################
## rewrite everything else to index.php
RewriteRule .* index.php [L]
</IfModule>
############################################
## Prevent character encoding issues from server overrides
## If you still have problems, use the second line instead
AddDefaultCharset Off
#AddDefaultCharset UTF-8
<IfModule mod_expires.c>
############################################
## Add default Expires header
##http://developer.yahoo.com/performance/rules.html#expires
ExpiresDefault «access plus 1 year»
ExpiresActive On
ExpiresByType image/gif «access plus 30 days»
ExpiresByType image/jpg «access plus 30 days»
ExpiresByType image/jpeg «access plus 30 days»
ExpiresByType image/png «access plus 30 days»
ExpiresByType image/x-icon «access plus 30 days»
ExpiresByType text/css «access plus 30 days»
ExpiresByType application/x-javascript «access plus 30 days»
</IfModule>
############################################
## By default allow all access
Order allow,deny
Allow from all
############################################
## If running in cluster environment, uncomment this
##http://developer.yahoo.com/performance/rules.html#etags
FileETag none - The .htaccess is optimized both as recommended by YSlow and Page Speed.
- Let us optimize our images using a superb tool from Yahoo! named Smush It! At YSlow you will see a link for all tools. Click it and navigate to All Smush It!. Upon clicking you would see a page something like the following:

- Next, download the optimized images and replace your local images. If you are reading this recipe for some LAMP app other than Magento, then you can use some other tools provided by YSlow such as compression of your js and css files. Kinda cool huh!
- For Page Speed, it's already applied most of the recommended rules except Parallelize downloads across hostnames. You can adopt it by using a CDN.
- There are so many CDN providers out there. You can choose any one and pull the static contents from a CDN. After completion of this one, if we run YSlow and Page Speed, it should be all green!

(Move the mouse over the image to enlarge.)
How it works...
YSlow and Page Speed both have online documentation to apply their rulesets. You can and should read it thoroughly to make it better.
- YSlow: http://developer.yahoo.com/performance/rules.html.
- Page Speed: http://code.google.com/speed/page-speed/docs/using.html.
Summary
In this article we saw how to overcome the most common pitfalls by applying the techniques described in the different recipes.
Further resources on this subject:
- Magento 1.4 Themes Design [Book]
- Magento 1.4 Development Cookbook [Book]
- Integrating Twitter with Magento [Article]
- Integrating Facebook with Magento [Article]
- Magento 1.4: Performance Optimization [Article]
- Getting Started with Magento Development [Article]
About the Author :
Nurul Ferdous
Nurul Ferdous is an open source enthusiast and IT specialist from Bangladesh who has long experience with various organizations from the military to multinational companies both at home and abroad. In fact he is a soldier turned programmer. He is currently working for TMSecure Inc. as an LAMP Consultant. He started his career with the Bangladesh Air Force. He also served in RAB as an intelligence staffer where he was nominated for the presidential police medal for his outstanding contribution to national security. He is a truly passionate programmer. He started his career in software development back in 2004 while he was working in the Bangladesh Air Force with Java.
His primary skills are as a PHP developer. He is a Zend Certified PHP5 Engineer, he contributes to a number of PHP projects, blogs on PHP-related topics, and presents talks and tutorials related to PHP development and the projects to which he contributes. He is also a certified professional on TDD and Code Refactoring.
He has served in some top-notch software companies both at home and abroad like BIPL, Right Brain Solutions Ltd., TMSecure Inc., NameDepot.com, Inc., and so on as programmer, software engineer, and consultant. Nurul Ferdous contributes to the open source community regularly.



Post new comment