How can I prevent wordpress wp_insert_term from leaking memory and slowing down?

I have been obsessing over this for over 2 days now. I need your help.

I have a simple loop from 1 to 5000 to insert wordpress terms. It seems like wp_insert_term is leaking memory somehow and script slows down.

Read More

Consider following script (If you’ll run it, you need to place it in root wordpress dir):

<?php

$full_start = microtime(true);

include_once 'wp-load.php';



for($i=1;$i<5000;$i++) {

$sub_start = microtime(true);

wp_insert_term('Some Genre Name '.$i, 'genres', array('description' => "Description"));

echo "AT: ".$i." Mem: ".memory_get_usage();

$sub_end = microtime(true);
echo " In: ".($sub_end - $sub_start)." seconds Golabls: ".count($GLOBALS)."n";

}

$full_end = microtime(true);

echo "Total time: ".($full_end - $full_start)." secondsn";

You will notice that as terms get added script slows down at it takes longer to insert. Also, the memory usage grows astronomically. I’m wondering what can be done to prent memory leak and whether or not the reason for slow down is memory usage. I did debug wp queries and they don;t seem to be the reason for the slowdown.

Any help would be greatly appreciated. I tried to profile it with xhprof, with no success.

Related posts

Leave a Reply

1 comment

  1. It’s probably been a long time and maybe you’ve already figured it out by now, but I recently came across this issue, so here’s the thing:

    wp_insert_posts(), at some point along its execution path, performs a call to get_terms(), retrieving all the term IDs of the taxonomy you’re working on. These IDs are also cached in WordPress’s cache.

    The cache’s size grows dramatically if there are plenty (1000s) of terms in your taxonomy (‘genres’ in your case), which causes high memory usage (maybe even a fatal error due to memory exhaustion depending on PHP’s and WordPress’s relevant limit).

    The only workaround I was able to implement was to count how many terms have been inserted, and to explicitly clear WordPress’s cache every some insertions (in the order of 100s).

    You can clear the cache by calling wp_cache_flush().

    For example, you can include this somewhere inside your loop:

    if ( $i % 500 == 0 ) {
        wp_cache_flush();
    }