Wordpress - Is there a downside of using wp_defer_term_counting?

Here are some thoughts on the issue, but please note that this is by no means a conclusive answer as there may be some things I have overlooked however this should give you an insight to the potential gotchas.


Yes, technically there could be consequences.

Where calling wp_defer_term_counting(true) becomes truly beneficial is when for instance you are performing a mass insertion to the database of posts and assigned terms to each object as part of the process.

In such a case you would do the following:

wp_defer_term_counting(true); //defer counting terms

//mass insertion or posts and assignment of terms here

wp_defer_term_counting(false); //count terms after completing business logic

Now in your case, if you are only inserting one post at a time, then deferring term counting will still benefit you however by not call wp_defer_term_counting(false) after your operation could leave you and or other parties involved with the request in a bind if you rely upon the term count for any other logic/processing, conditional or otherwise.

To explain further, let's say you do the following:

Assume we have 3 terms within a taxonomy called product_cat, the IDs for those terms are 1 (term name A), 2 (term name B) and 3 (term name C) respectively.

Each of the above terms already has a term count of 5 (just for the example).

Then this happens...

wp_defer_term_counting(true); //defer counting terms

$post_id = wp_insert_post($data);

wp_set_object_terms($post_id, array(1, 2, 3), 'product_cat');

Then later in your logic you decide to fetch the term because you want to assess the amount of objects associated with that term and perform some other action based on the result.

So you do this...

$terms = get_the_terms($post_id, 'product_cat');

//let's just grab the first term object off the array of returned results
//for the sake of this example $terms[0] relates to term_id 1 (A)
echo $terms[0]->count; //result 5

//dump output of $terms above
array (
  0 => 
  WP_Term::__set_state(array(
     'term_id' => 1,
     'name' => 'A',
     'slug' => 'a',
     'term_group' => 0,
     'term_taxonomy_id' => 1,
     'taxonomy' => 'product_cat',
     'description' => '',
     'parent' => 0,
     'count' => 5, //notice term count still equal to 5 instead of 6
     'filter' => 'raw',
  )),
)

In the case of our example, we said that term name A (term_id 1) already has 5 objects associated with it, in otherwords already has a term count of 5.

So we would expect the count parameter on the returned object above to be 6 but because you did not call wp_defer_term_counting(false) after your operation, the term counts were not updated for the terms applicable (term A, B or C).

Therefore that is the consequence of calling wp_defer_term_counting(true) without calling wp_defer_term_counting(false) after your operation.

Now the question is of course, does this effect you? What if you have no need to call get_the_terms or perform some action that retrieves the term where by you use the count value to perform some other operation? Well in that case great, no problem for you.

But... what if someone else is hooked onto set_object_terms action in the wp_set_object_terms() function and they are relying upon the term count being correct? Now you see where the consequences could arise.

Or what if after the request has terminated, another request is performed that retrieves a taxonomy term and makes use of the count property in their business logic? That could be a problem.

While it may sound far fetched that count values could be of much harm, we cannot assume the way such data will be used based on our own philosophy.

Also as mentioned in the alternate answer, the count as seen on the taxonomy list table will not be updated either.

In fact the only way to update term counts after you defer term counting and your request has ended is to manually call wp_update_term_count($terms, $taxonomy) or wait until someone adds a term for the given taxonomy either via the taxonomy UI or programmatically.

Food for thought.