Magento has a built-in cache. In version 1.5.0.1 Magento added a Full Page Cache option to Magento which gives us the ability to use holepunch techniques to cache blocks. This section here doesn't deal with the full page cache at all, rather just uses the standard Magento cache and we add the ability for Magento to cache category lists
In the below examples, we haven't yet added the caching. We use the following (example) command from Apache Benchmark on the local machine the tests are being run on to run the tests, which eliminates network contention
ab -c 5 -n 100 http://www.testdomain.com/category
Before: Stats Showing # of Database Queries & Time Taken for 100 requests
Below, you can see that we had 153 requests to the database. The total time to run the tests was 19.452 seconds resulting in 5.14 requests per second. The median wait time to process each request was 666 milliseconds

Concurrency Level: 5 Time taken for tests: 19.452007 seconds Complete requests: 100 Failed requests: 0 Write errors: 0 Total transferred: 12481500 bytes HTML transferred: 12433700 bytes Requests per second: 5.14 [#/sec] (mean) Time per request: 972.600 [ms] (mean) Time per request: 194.520 [ms] (mean, across all concurrent requests) Transfer rate: 626.57 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.4 0 3 Processing: 608 961 579.6 700 4578 Waiting: 580 924 581.1 666 4542 Total: 608 961 579.7 700 4579 Percentage of the requests served within a certain time (ms) 50% 700 66% 851 75% 1053 80% 1160 90% 1670 95% 2258 98% 2778 99% 4579 100% 4579 (longest request)
Below are the database statistics provided by the profiler
Executed 153 queries in 0.0114271640778 seconds Average query length: 7.46873469135E-5 seconds Queries per second: 13389.1487826 Longest query length: 0.000326871871948
After: Stats Showing # of Database Queries & Time Taken for 100 requests
Now we have made the changes, you can see that we had 64 requests to the database. The total time to run the tests was 12.546 seconds resulting in 7.97 requests per second. The median wait time to process each request was 439 milliseconds.

Concurrency Level: 5 Time taken for tests: 12.546279 seconds Complete requests: 100 Failed requests: 0 Write errors: 0 Total transferred: 12481500 bytes HTML transferred: 12433700 bytes Requests per second: 7.97 [#/sec] (mean) Time per request: 627.314 [ms] (mean) Time per request: 125.463 [ms] (mean, across all concurrent requests) Transfer rate: 971.44 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.0 0 0 Processing: 409 619 339.7 474 2258 Waiting: 383 583 339.5 439 2222 Total: 409 619 339.7 474 2258 Percentage of the requests served within a certain time (ms) 50% 474 66% 541 75% 625 80% 715 90% 922 95% 1518 98% 1928 99% 2258 100% 2258 (longest request)
Below are the database statistics provided by the profiler
Executed 64 queries in 0.00508761405945 seconds Average query length: 7.94939696789E-5 seconds Queries per second: 12579.5705516 Longest query length: 0.000263929367065
This equates to a 50% speedup for category listings
How to Make the Code Changes
We need to override the core List.php file to make these changes. To do this via SSH:
mkdir -p app/code/local/Mage/Catalog/Block/Product/ cp app/code/core/Mage/Catalog/Block/Product/List.php app/code/local/Mage/Catalog/Block/Product/List.php
This overrides our core product list file with our own version that we can now modify accordingly. Now modify the file like so:
app/code/local/Mage/Catalog/Block/Product/List.php
class Mage_Catalog_Block_Product_List extends Mage_Catalog_Block_Product_Abstract { /** * Default toolbar block name * * @var string */ protected $_defaultToolbarBlock = 'catalog/product_list_toolbar';to be
class Mage_Catalog_Block_Product_List extends Mage_Catalog_Block_Product_Abstract { protected function _construct() { $this->addData(array('cache_lifetime' => 9999999999,)); } public function getCacheTags() { return array(Mage_Catalog_Model_Product::CACHE_TAG); } public function getCacheKey() { return $this->getRequest()->getRequestUri(); } /** * Default toolbar block name * * @var string */ protected $_defaultToolbarBlock = 'catalog/product_list_toolbar';Credit for much of this goes to Chris Farley on Magento Forums