BEAR - WooCommerce Bulk Editor and Products Manager Professional

Bulk edit thousands of WooCommerce products: speed, memory and timeouts

To bulk edit thousands of WooCommerce products, the number of products is rarely the problem. BEAR shows one page of the table at a time and writes in small batches, so a catalogue of 60,000 products opens nearly as fast as one of 600. What makes the editor slow, run out of memory or stop with a 504 is something else: how many taxonomies and terms it has to draw, how many variations end up on one page, how much PHP memory and time the server gives each request, and what other plugins do every time a product is saved. Below is each of these, how to recognise it, and what to change.

What actually costs time in the bulk editor

  • Taxonomies and terms. When the editor page opens, the Filters and Bulk Edit panels are built with a drop-down for every product taxonomy (categories, tags, every attribute, custom taxonomies) holding every term, unused ones included. The field list also loads every attribute with all its terms. Ten thousand terms means ten thousand options to build on the server and to render in the browser.
  • Rows on the page. The table loads only the current page, but every row is a full product object, and with the variations switch on, every variation of every variable product on the page becomes a row too.
  • Each write. A bulk edit saves products through WooCommerce, and every plugin hooked to product saving runs once per product.
  • The server's limits. PHP memory per request, the time a request may run, and the number of form fields PHP accepts.

The total number of products affects only how many batches a bulk run takes, not how fast the page opens.

Too many taxonomies, attributes or terms

A shop with a few hundred categories and a few dozen attributes works fine. Trouble starts with thousands of terms, and it typically has one of three origins: an attribute or taxonomy holding a unique value per product (a UPC, a model code, a supplier reference), attributes duplicated by imports (Color, Colour, color-2), or a huge category tree. The signs are a page that takes a minute to open, a browser tab that freezes on the category popup, or Maximum call stack size exceeded in the console.

What to change, from the most effective:

  1. Move unique values out of taxonomies. A value that belongs to one product is a field, not a term. Keep it in a meta field and edit it through the Meta Fields tab; then delete the taxonomy or attribute.
  2. Clean up attributes. Merge duplicates and delete terms nothing uses in Products > Attributes. The editor loads empty terms too.
  3. Keep heavy taxonomies out of the panels. These filters remove taxonomies from the Filters and the Bulk Edit panel; the products keep their terms.
// Child theme functions.php or a code snippets plugin.
// BEAR: do not draw these taxonomies in the Filters and Bulk Edit panels.
function bear_skip_heavy_taxonomies( $taxonomies ) {
    foreach ( array( 'pa_model-code', 'product_tag' ) as $slug ) { // your taxonomy slugs
        unset( $taxonomies[ $slug ] );
    }
    return $taxonomies;
}
add_filter( 'woobe_filter_taxonomies', 'bear_skip_heavy_taxonomies' );
add_filter( 'woobe_bulkedit_taxonomies', 'bear_skip_heavy_taxonomies' );

To leave all attributes out of the two panels at once:

// BEAR: no attribute (pa_) drop-downs in the Filters and Bulk Edit panels.
add_filter( 'woobe_hide_filters_by_attribute', '__return_true' );
add_filter( 'woobe_hide_bulk_by_attribute', '__return_true' );

Also switch off the taxonomy columns you do not edit in the Settings tab: a column that is off is not drawn for any row. With thousands of categories, change categories in the Bulk Edit tab rather than in the popup of a table cell, which has to draw the whole tree in the browser every time it opens; the category bulk edit article shows how.

Variations multiply the rows

The variations switch on the tools panel adds the variations of every variable product on the page to the table. Ten products with 300 variations each is 3,000 rows: 3,000 product objects in PHP memory for one request and 3,000 rows for the browser to draw. Products with hundreds of variations are the most common reason for a memory error on the table request.

  • Before switching variations on, filter by product type = variable and lower the rows per page to 10 or 5 with the selector under the table. The variations documentation recommends the same.
  • Do not edit variations row by row. In the Bulk Edit tab, with the switch on, pick the attribute combinations to change and the operation runs over the variations of all filtered products in batches.
  • Set Default products count per page in Settings to a moderate value so the editor does not open on a heavy page.

PHP memory and settings that will not save

Allowed memory size of 134217728 bytes exhausted in the debug log, a 500 error when the editor or its Settings tab opens, or a table request that fails while other pages work: the request needed more memory than PHP allows. Raise the limit in wp-config.php, above the line that says to stop editing:

define( 'WP_MEMORY_LIMIT', '256M' );
define( 'WP_MAX_MEMORY_LIMIT', '512M' );

WordPress can only raise memory up to PHP's own memory_limit, which the host sets. If the error still names the old number, ask the host to raise memory_limit or change it in the hosting panel. On large catalogues 256 MB is a reasonable floor; reduce taxonomies and variations rather than raising it without end.

A different limit causes Settings that save only partly. Every attribute is a field in the Settings tab, and every field sends several values, so a shop with hundreds of attributes sends thousands of values in one save. PHP keeps the first max_input_vars (1000 by default) and silently drops the rest, so changes at the bottom of the list are lost. Raise max_input_vars to 5000 or more in the hosting panel or php.ini, or drag the fields you work with to the top of the list.

Long bulk runs and 502 or 504 timeouts

A bulk edit does not run as one long request. The server first returns the IDs of the products to change, then the browser sends them back in batches, one request each, and the progress bar moves per batch. A 502 or 504 in the middle of a run means one batch took longer than the server allows.

  • Lower the batch size. Number of posts processed at a time in the Settings tab ranges from 10 (for weak shared hosting) to 100, with 30 (optimal) as the default. Halve it and run again. Smaller batches take longer in total but each request stays short.
  • Split the work. Run the same operation per category or per price range. History records each run, so each can be reverted on its own.
  • Server time limits. PHP's max_execution_time and the web server's timeouts (Apache Timeout, nginx fastcgi_read_timeout or proxy_read_timeout) decide how long one batch may take. Many managed hosts have a fixed gateway limit; there, the batch size is the setting to change.
  • Plugins hooked to product saving. If ten products take as long as a minute, the time goes into other plugins: search indexes, feeds, sync connectors, page builders, cache purges. Isolating plugins during bulk edits shows how to keep them out of BEAR's requests.

A run that stops halfway leaves the first batches written. Its History record keeps the state terminated instead of completed and counts the products written so far; revert it, or run the operation again on the same filter if it is safe to apply twice (a set new value is, an increase by % is not).

Other things that slow the editor page down

The author drop-down on shops with many users

When the editor opens, it builds the author list for the filter and bulk edit panels by asking WordPress for every user whose role can publish. On a site with a very large user table, or with a plugin that rewrites user queries, that query alone can take minutes and end in a 504 before the page appears. The woobe_users_args filter replaces the query, for example with the users who actually own products:

// Child theme functions.php or a code snippets plugin.
// BEAR: list only users who already own products in the author drop-down.
add_filter( 'woobe_users_args', function ( $args ) {
    global $wpdb;

    $author_ids = get_transient( 'bear_product_author_ids' );
    if ( false === $author_ids ) {
        $author_ids = $wpdb->get_col( "SELECT DISTINCT post_author FROM {$wpdb->posts} WHERE post_type = 'product'" );
        set_transient( 'bear_product_author_ids', $author_ids, DAY_IN_SECONDS );
    }

    return array(
        'fields'  => array( 'ID', 'display_name' ),
        'include' => empty( $author_ids ) ? array( 0 ) : array_map( 'intval', $author_ids ),
        'orderby' => 'display_name',
    );
} );

A user who owns no product yet will not appear in the list until the cached list expires a day later; delete the bear_product_author_ids transient to refresh it at once.

Object cache flushes and admin optimisation

On sites with Redis or Memcached, BEAR empties the object cache before drawing the table, so the whole site rebuilds its cache every time the table loads. On a busy large shop that is noticeable; the woobe_use_cache_flush filter switches it off, with the trade-off explained in bulk editor filter not working. Page cache and optimisation plugins that minify, combine or delay scripts in wp-admin slow down every request of the editor; exclude /wp-admin/ from those features.

Checklist for a large catalogue

  • No taxonomy holds one term per product; duplicate attributes are merged and unused terms deleted.
  • Taxonomies you never filter or bulk edit by are removed from the panels with woobe_filter_taxonomies and woobe_bulkedit_taxonomies.
  • Rows per page are 10 or fewer while the variations switch is on.
  • PHP memory_limit is 256 MB or more and max_input_vars is high enough for your Settings tab.
  • Number of posts processed at a time is low enough that no batch reaches the server's timeout.
  • Nothing to do about BEAR's rows in wp_options: the ones that can grow, the per-user settings (woobe_options_ plus the user ID) and the per-user memory (woobe_memory_ plus the user ID), are written without autoload, so shop pages never load them, and the memory rows hold only the current filter and bulk data, which expire after a day.

If the editor is still slow after these changes, open a topic on the BEAR support forum with the number of products, variations per product, taxonomies and terms, and the error the server or the browser console shows.