0

I want to track how many views a post has had for every day. So that I can get all kind of interesting trends out of it later. For example most visit last three days.

But what is the best way to store this data? Most tutorials on google search is about just storing the total views. Not per day. If I would store the day views in the same way I would probably just make a meta save like this:

update_post_meta($post_id, "views_$year-$month-$day", $views + 1);

But I'm not sure that is the best way when I easy want to get different kind of stat results from the database? Feels like it gonna be a lot of unnecessary large database requests. And that WP post meta datas are made for other kind of data storing.

2

Put simply, you don't, and you shouldn't

The Problems

Race Conditions Make the Data Super Unreliable

Updating post meta, options, terms, etc is not an atomic operation. You need to fetch the view count, add 1 to it, then send it back to the database.

During that process, another page load is occuring which does the same thing, leading to the following situation:

  • user 1: get_post_meta 5!
  • user 2: get_post_meta 5!
  • user 1: adds 1, 6!
  • user 2: adds 1, 6!
  • user 1: saves update_post_meta, 6 views!
  • user 2: saves update_post_meta, 6 views!

Now your counter says 6, when it should say 7.

Huge Performance Costs

Database writes are a lot more expensive than reads, and this system involves a database write on every page load. This will not scale, and will have significant performance and speed problems.

So How Do I Track Page Views?

External services and software. These kinds of systems need to be built in a particular way so that they give reliable information without being super slow. It isn't an easy task.

So instead, use a 3rd party service, and pull that information in at regular intervals. You could make a fresh request every time you view a page to get 100% accurate data, but that would be even slower, you wouldn't be able to cache the pages, and load times could be higher than 10 seconds, which is awful for SEO and UX.

On my own site, I pull Google Analytics data in every hour for the top 10 viewed posts, the 10 most recent, and 10 posts that have not been checked recently ( I save a timestamp for when they were last checked, and use the 10 oldest timestamps )

  • You're probably right. What GA data do you put in? And you mean "put in" as store as post meta datas or what? Or you mean for changing post tags? – Peter Westerlund Aug 15 '17 at 13:26
  • I store the view counts in post meta yes, I use this plugin, but you can use Jetpack APIs with WP.com stats too github.com/cftp/popular – Tom J Nowell Aug 15 '17 at 13:30
  • Okay, how do you code to get different post lists out based on that meta datas then? Like "Give me the 5:th first posts with the highest values of THAT meta data". And about the Popular plugin. I need something more easy to install. I have no "composer" and the site is on Rackspace hosting. – Peter Westerlund Aug 15 '17 at 20:23
  • You can use composer on your local machine then upload it, you wouldn't run composer on a server unless you're a sysadmin or a deploy bot/script. Install composer then run composer install in that folder. Eitherway the plugin was merely an example, the answer is still the same, pull the data in from a 3rd party service dont store it yourself. Also the question about how to query posts via meta would make a good question, you should ask that as a separate question – Tom J Nowell Aug 16 '17 at 17:30
1

When you want to store the data for a specific period of time, you can use the Transients API. But, this API is good for small amount of data, such as theme options or similar data.

What you can do is, to store the post views normally, and then run a cron job each day and clear the views. Let's take a look at a simple example.

// You update the view counts by using post meta
update_post_meta( $post_id, "view_count", $views + 1 );
// Now, let's run a task each day at 00:00 and clear these counts.
// If the cron is not scheduled, schedule it for 00:00 
if ( ! wp_next_scheduled( 'clear-post-counts' ) ) {
  wp_schedule_event( strtotime( '00:00:00' ), 'daily', 'clear-post-counts' );
}
// Every time this action hook is triggered, the 
// callback function is run to clear the meta data
add_action('clear-post-counts', 'clear_post_counts');
function clear_post_counts(){
    // Get a list of all posts
    $posts = get_posts();
    // For each post, set the post views to 0
    foreach( $posts as $post ) {
        update_post_meta( $post->ID, "view_count", 0);
    }
}

The code is just an example of where to get started. You can customize it to fit your specific needs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.