Counting pageviews on high-traffic cached sites

Our site is quite high traffic and we use both nginx and w3 total cache to handle the load. We’ve previously been using wp-postviews to count the page views, but it seems to be locking the postmeta table now, and often doesnt count views at all. It’s unreliable at best.

Can anyone suggest a way for us to count page views and put them into the DB, or any specific workable solutions?

Read More

My initial thoughts are to have the view count done via javascript to update a separate database, then a cron job at the end of each day to merge the results, but I’m not sure where to start.

Thanks in advance

Related posts

Leave a Reply

3 comments

  1. It really depends what you need to view counts for – if it’s just for seeing traffic stats, then use Google Analytics or any number of javascript tracker based analytics tools.

    If you need integration of page view counts and the ability to do things like order post by views, then you can either

    • spend some time optimising your database – some options and things to consider
      • more memory for MySQL
      • change the postmeta table to be InnoDB
      • get a separate database server
      • make sure you’ve tuned your MySQL settings (use mysqltuner as a starting point)

    OR

    • Use something like Piwik and spend time integrating it (it has a decent API) with WordPress.
  2. Here’s how you do it, assuming you have a memory caching extension active:

    (I’m going to use APC as an example here because it will be bundled with PHP 6)

    // set this to the current post id
    $post_id = get_the_ID();
    
    // this will attempt to get the post view count from cache (the memory)
    $page_views = apc_fetch("post_{$post_id}_views");
    
    // if it exists, increase the counter (again, only in memory)
    if($page_views !== false){
      $page_views = apc_inc("post_{$post_id}_views");
    
      // write the data to the database every ...let's say 100 views
      if(($page_views % 10) == 100)
        update_your_database_here();
    }
    
    // doesn't exist; most likely this is the first view, so create the cache entry
    else{
      apc_store("post_{$post_id}_views", 1);
      $page_views = 1;
    }
    
    // show it
    printf('This post has %d views', $page_views);
    

    You can choose to use WP’s functions – wp_cache_incr() or wp_cache_decr() + W3TC with APC selected. But personally I would avoid using any cache plugins and create my own object cache handler which I can drop in the wp-content directory.

    You can also use xcache for this too, it doesn’t matter – The idea is that you need to store the count in memory up to a certain point, to avoid any disk writes. Since your site has high-traffic I assume you own a dedicated server, on which you can install your own PHP extensions etc. Shared hosters won’t allow you to cache data in memory for obvious reasons…