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:

Object Cache for WordPress

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:

2,726 views

ruslany on March 5th 2010 in PHP, WordPress

PoorFairAverageGoodExcellent (2 votes, average: 5.00 out of 5)

16 Responses to “Make WordPress faster on IIS with WinCache 1.1”

  1. Gravatar ImagePHP on Windows « Coder Kung Fu! responded on 07 Mar 2010 at 8:49 am #

  2. Gravatar ImageChris responded on 16 Mar 2010 at 7:32 am #

    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?

  3. Gravatar Imageruslany responded on 18 Mar 2010 at 1:10 pm #

    @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.

  4. Gravatar ImageChris responded on 19 Mar 2010 at 4:40 pm #

    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

  5. Gravatar ImageWordpress, IIS, Wincache « Кокоевсёзелёное responded on 24 Mar 2010 at 8:40 am #

    [...] Wincache 1.1.0305.0 (бета) и object-cache.php там же получаем ~30 requests per [...]

  6. Gravatar ImageChris responded on 26 Mar 2010 at 5:01 am #

    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.

  7. Gravatar Imageruslany responded on 29 Mar 2010 at 5:17 pm #

    @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; ?>

  8. Gravatar ImageManuel responded on 31 May 2010 at 7:54 am #

    What is with the enablecache=treu setting in wp-config.php

    Must this flag be true when using the api?

  9. Gravatar Imageruslany responded on 01 Jun 2010 at 10:22 am #

    @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.

  10. Gravatar ImageWordPress does Windows - The WordPress Podcast responded on 01 Jun 2010 at 3:40 pm #

    [...] 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 [...]

  11. Gravatar ImageWordpress Podcast | Josh Holmes responded on 01 Jun 2010 at 9:22 pm #

    [...] 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 [...]

  12. Gravatar ImageMmos responded on 13 Jun 2010 at 3:37 pm #

    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.

  13. Gravatar Imageruslany responded on 14 Jun 2010 at 3:44 pm #

    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.

  14. Gravatar ImageMmos responded on 14 Jun 2010 at 6:51 pm #

  15. Gravatar ImageMmos responded on 14 Jun 2010 at 6:52 pm #

    Also that version worked with both 2.7.1 and 2.9.2 for us.

  16. Gravatar ImageMmos responded on 23 Jun 2010 at 7:56 am #

    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.

Trackback URI | Comments RSS

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

XML Markup: If You want to add XML code to the comment please XML encode it first, otherwise the code will not show up.

Recently Published Articles