wp_defer_term_counting()
Allows deferring the count of posts for a term (taxonomy element).
The function is designed to speed up import operations or adding/removing a large number of posts.
By default, when adding or removing a post, wp_update_term_count() is immediately called, and WordPress recalculates the number of posts in the associated term. If there are many posts, this creates hundreds of unnecessary recalculations and significantly slows down performance.
This function allows temporarily disabling the count: WordPress simply remembers the term IDs where changes occurred. When all operations (for example, importing 500 posts) are completed, you can call the count once, and it will update the number of posts at once for all affected terms.
That is, instead of dozens or hundreds of recalculations, you get one final recalculation — faster and more efficient.
Example:
wp_defer_term_counting( true ); // disable counting // do what is needed wp_defer_term_counting( false ); // re-counting for all
See also:
-
wp_suspend_cache_addition() - function for importing large data.
-
wp_defer_comment_counting() - similar function, but for comments.
- wp_suspend_cache_invalidation().
No Hooks.
Returns
true|false. Whether post counting is enabled or disabled for the taxonomy element.
Usage
wp_defer_term_counting( $defer );
- $defer(true|false)
true- will disable the actual counting of posts for the function wp_update_term_count() and enable saving the term IDs for which counting needs to be donefalse- will process all saved term IDs - will count posts for each saved term.null- will simply return the current value of whether post counting is enabled or disabled.
Default: null
Examples
#1 Speeding up the import of a large number of posts
Let's say we need to add 1000 posts to the database, each of which will be assigned a different category and tags. We have 20 categories and 50 tags on our site, i.e. the same categories and tags will get different posts. Therefore, in this case you can optimize the import code, postponing recalculation of the number of posts for each category and tag.
$posts_data = [ ... ];
// disables recalculation of posts in categories and collects IDs
wp_defer_term_counting( true );
// import
foreach( $posts_data as $post_data ){
wp_insert_post( $post_data );
}
// recalculate posts in categories for all collected IDs
wp_defer_term_counting( false ); #2 Pending recalculation of posts in tags when deleting tags
Suppose we have a lot of similar tags and we want to optimize tags - gather all similar tags into groups, select the main tag from them and move all the posts to the main tag and delete the other tags.
You can delete tags and move their posts to the main tag with wp_delete_term() with additional parameters:
$delete_tag = 25; $main_tag = 15; wp_delete_term( $delete_tag, 'post_tag', [ 'default'=>$main_tag, 'force_default'=>1 ] );
Function wp_update_term_count() will be called for each moved post. So, for example, if we have 4 tags in a group (one main tag) and three non-main tags contain, for example, 20 posts, then when we delete these 3 tags, 20 posts will go to the main tag and the recount function will be called 20 times.
To avoid this and to call the recalculation function once instead of 20 you can postpone the recalculation:
$delete_tags_groups = [ ... ];
// disables tag post counts and collects tag IDs
wp_defer_term_counting( true );
// tag removal
foreach( $delete_tags_groups as $tags ){
$main_tag = array_shift( $tags );
foreach( $tags as $delete_tag ){
wp_delete_term( $delete_tag, 'post_tag', [ 'default'=>$main_tag, 'force_default'=>1 ] );
}
}
// recalculate tag posts for all collected tag IDs
wp_defer_term_counting( false ); #3 Speeding up the deletion of posts
For example we need to delete 1,000,000 posts, to speed up this process you can use the following code:
wp_suspend_cache_addition( true );
wp_defer_term_counting( true );
$to_delete = [ 15,12,14, ... ];
// disables recalculation of posts in categories and collects IDs
wp_defer_term_counting( true );
// import
foreach( $to_delete as $post_id ){
wp_delete_post( $post_id, true );
}
// recalculate posts in categories for all collected IDs
wp_defer_term_counting( false );
Changelog
| Since 2.5.0 | Introduced. |
wp_defer_term_counting() wp defer term counting code WP 6.9
function wp_defer_term_counting( $defer = null ) {
static $_defer = false;
if ( is_bool( $defer ) ) {
$_defer = $defer;
// Flush any deferred counts.
if ( ! $defer ) {
wp_update_term_count( null, null, true );
}
}
return $_defer;
}