I used post meta (in a unusual way) instead of transients as regenerating the data was too expensive. And I learned about fields='ids' in WP_Query.
Last year I was working on a WooCommerce site that aimed to be similar to Groupon. The client asked for dynamic updating of category and sub category counts and that these be displayed in a drop down beside the category names.
When working on a site I often try to learn something new or improve how I implement things, use a new WordPress feature. The category and sub category counts would constantly change as products were added and edited. I felt that the data was a good candidate for transients (where the data expires after a specified amount of time). When rendering the drop down lists the code would use the transient if available, otherwise it would regenerate the data and store it in the transient.
Learn Something New
During development the site had almost 1000 products and regenerating the data frequently crashed things. I decided to move the data generation code to a standalone script so that it had as much available memory as possible. While this improved things it still used a lot of memory. Then I learned something new: in the WP_Query call I could specify the fields returned to limit it to just the post IDs – this does a SQL ‘SELECT ID‘ instead of ‘SELECT *‘. I then loop through each product, query some post meta, create a multi dimension array and store it in the transient. I scheduled this code to run every hour.
To get some time and memory usage data I created a new site and programatically added 1000 products. I used the above code and measured the peak memory usage (memory_get_peak_usage) and process time (microtime) for each.
The traditional loop used 9MB and took 1.33 seconds while the fields=’ids’ loop used 5MB and took 0.8 seconds.
With the transient generation code no longer part of the core theme code (yes, I realise that it should have been moved into a plugin – that was something to learn during another project) the drop down code could not be called if the transient data was not available. While the risk was low that the transient data would timeout and be deleted, the client required the category and sub category counts. I had to ensure that they were always available so I decided to move the data to post meta.
To ensure that it would not be deleted I used post ID 1 – the “Hello World” post that is created when a site is created. The post had already been deleted so there would never be another post with that ID and therefore never a reason for a post with ID 1 to be deleted, taking its post meta with it.
The function calls to retrieve a transient and post meta are very similar so it was an easy switch.
A transient would have been the right way to store the data, regenerating it was too expensive.