Make WordPress faster on IIS with WinCache 1.1
This post explains how to improve performance of WordPress on Windows by using the WinCache Extension 1.1 – Beta for PHP. You probably already know that just by enabling the WinCache extension and without any code changes it is possible to get a significant increase in WordPress performance – this is described in details in PHP on Windows: The WinCache 1.0 Benchmark. But this can be taken even further by using the user cache API’s available in WinCache 1.1 release.
To configure WordPress to use WinCache user cache API’s copy the following code and put it in the file named object-cache.php located at the /wp-content/ directory of your WordPress site. Note that this code was copied from here and the only change was to replace all the APC cache function with corresponding WinCache functions.
<?php
/*
Name: WinCache Cache
Description: WinCache backend for the WP Object Cache.
Version: 0.1
URI: http://ruslany.net/
Author: Ruslan Yakushev
Install this file to wp-content/object-cache.php
Big thanks to Mark Jaquith (http://markjaquith.wordpress.com/)
whose apc-object-cache.php was used as a basis for this code.
*/
// gracefully revert to default cache if WinCache is not installed
if ( !extension_loaded('wincache') ||
!function_exists('wincache_ucache_get') ||
strcmp(ini_get('wincache.ucenabled'), "1") ) {
include_once(ABSPATH . WPINC . '/cache.php');
} else {
function wp_cache_add($key, $data, $flag = '', $expire = 0) {
global $wp_object_cache;
return $wp_object_cache->add($key, $data, $flag, $expire);
}
function wp_cache_close() {
return true;
}
function wp_cache_delete($id, $flag = '') {
global $wp_object_cache;
return $wp_object_cache->delete($id, $flag);
}
function wp_cache_flush() {
global $wp_object_cache;
return $wp_object_cache->flush();
}
function wp_cache_get($id, $flag = '') {
global $wp_object_cache;
return $wp_object_cache->get($id, $flag);
}
function wp_cache_init() {
global $wp_object_cache;
$wp_object_cache = new WP_Object_Cache();
}
function wp_cache_replace($key, $data, $flag = '', $expire = 0) {
global $wp_object_cache;
return $wp_object_cache->replace($key, $data, $flag, $expire);
}
function wp_cache_set($key, $data, $flag = '', $expire = 0) {
global $wp_object_cache;
return $wp_object_cache->set($key, $data, $flag, $expire);
}
class WP_Object_Cache {
var $global_groups = array ('users', 'userlogins', 'usermeta');
var $cache = array ();
function add($id, $data, $group = 'default', $expire = 0) {
return $this->set($id, $data, $group, $expire);
}
function delete($id, $group = 'default') {
$key = $this->key($id, $group);
$result = wincache_ucache_delete($key);
if ( false !== $result )
unset($this->cache[$key]);
return $result;
}
function flush() {
wincache_ucache_clear();
return true;
}
function get($id, $group = 'default') {
$key = $this->key($id, $group);
if ( isset($this->cache[$key]) )
$value = $this->cache[$key];
else
$value = wincache_ucache_get($key);
/* echo "Cache key: $key<br/>";
echo 'Cache value:<br/>';
var_dump($value);
echo '<br/>'; */
if ( NULL === $value )
$value = false;
$this->cache[$key] = $value;
return $value;
}
function key($key, $group) {
global $blog_id;
if ( empty($group) )
$group = 'default';
if (false !== array_search($group, $this->global_groups))
$prefix = '';
else
$prefix = $blog_id . ':';
return md5(ABSPATH . "$prefix$group:$key");
}
function replace($id, $data, $group = 'default', $expire = 0) {
return $this->set($id, $data, $group, $expire);
}
function set($id, $data, $group = 'default', $expire = 0) {
$key = $this->key($id, $group);
$result = wincache_ucache_set($key, $data, $expire);
if ( false !== $result )
$this->cache[$key] = $data;
return $result;
}
function stats() {
$wincache_info = wincache_ucache_info();
echo "<p>\n";
echo "<strong>Cache Hits:</strong> {$wincache_info['total_hit_count']}<br/>\n";
echo "<strong>Cache Misses:</strong> {$wincache_info['total_miss_count']}<br/>\n";
echo "</p>\n";
if ( ! empty($this->cache) ) {
echo "<pre>\n";
print_r($this->cache);
echo "</pre>\n";
}
}
function WP_Object_Cache() {
// Nothing here
}
}
}
?>
You can also download the code by using the link below:
Make sure that the code is saved in a file called object-cache.php inside of the /wp-content/ directory.
That should be all you need to do. To verify that the WordPress is actually using the object cache use the WinCache Statistics Script and check the “User and Session Cache” page:


[...] WordPress on IIS (http://ruslany.net/2010/03/make-wordpress-faster-on-iis-with-wincache-1-1/) [...]
Odd problem with this, when i enable this it caches i see it working good, but my plugins page after installing or deleting a plugin still shows/doesnt show the plugin i just modified, is their a way to fix this?
@Chris: this looks like a side effect or a bug in the object cache implementation in wordpress. I am not aware of an easy way to fix this. I suspect that the plugins page will show correct information once the cached data has expired or the IIS worker process recycles.
ya but its driving me nuts lol, i install plugin, have to recycle the pool, then the plugin page updates LOL, any ideas on a workaround, i love it it makes the site really fly but getting things up and running is a beast with this, i guess i cud disable the cache-object every time i want to do plugin or admin maintenance but thats also kinda dificult, wish their was an easy way to disable and enable it lol
[...] Wincache 1.1.0305.0 (бета) и object-cache.php там же получаем ~30 requests per [...]
hey ruslany, can you post the code u used for that wincache stats on the right?
wud be cool to have that in the dashboard widgets.
@Chris: here it is:
<?php if ( function_exists('wincache_ocache_fileinfo') ) : ?><li>
<h2>WinCache</h2>
<div id="wincache">
<ul>
<?php $wincache_stats = wincache_ocache_fileinfo(); ?>
<li class="noimage"><strong><?php echo $wincache_stats['total_file_count']; ?></strong> cached PHP files</li>
<li class="noimage"><strong><?php echo $wincache_stats['total_hit_count']; ?></strong> cache hits</li>
<li class="noimage"><strong><?php echo $wincache_stats['total_miss_count']; ?></strong> cache misses</li>
<li class="noimage"><a href="http://ruslany.net/2010/03/more-performance-improvements-in-wincache-1-1-beta/">Learn More...</a></li>
</ul>
</div>
</li>
<?php endif; ?>
What is with the enablecache=treu setting in wp-config.php
Must this flag be true when using the api?
@Manuel: I am not sure how that flag relates to this. For example I set it to true and to false and it did not make a difference for me. Currently on my site I have it set to false and the object cache works fine.
[...] SQL Server for the database store as shown on sites like oddlyspecific.com for example with performance enhancements. Josh also highlighted some of the steps Microsoft is taking to make deployment of [...]
[...] result in a 3x or so improvement in performance in PHP on IIS. RuslanY has a great post on getting WinCache support into WordPress. And if you want to see how well it’s working, check out this module that shows you WinCache [...]
Hi, wincache is really very cool, but one issue I am seeing when I enable the object cache is the pending comments count (and also the plugin count) in the wordpress admin do not update.
I remember there was the same issue with wordpress 2.7.1 and an opcode object cache we were using at the time, and it eventually got fixed (it was working fine for us with eaccelerator opcode cache)
Any chance this could be fixed for wordpress 2.9.2 and wincache object cache?
Thanks.
Hi Mmos, when it worked for you on 2.7.1 – did you use exact same code for the object-cache.php as in here? I also noticed that the plugin count does not get updated. Apparently all the items that wordpress puts into the the cache do not expire. But I did not know that it was different in 2.7.1.
Hi, we were using the one from this site:
http://neosmart.net/dl.php?id=12
it can be downloaded here:
http://neosmart.net/downloads/software/WordPress/Plugins/object-cache/xcache-object-cache_0.6.zip
Also that version worked with both 2.7.1 and 2.9.2 for us.
Hi, any update on getting the object cache to work with wordpress?
Also was just wondering, if wincache’s user cache is enabled (vide object-cache) in wordpress, then would you say using a plugin like wp super cache with iis output caching is no longer needed?
Basically my question is does wincache perform as well as iis output caching, or would you still recommend using both?
We’re hosting a site with 12M+ page views per month so I’m trying to squeeze the most out of our wordpress/iis install.