Running 100+ WooCommerce Stores with Wordpress Multisite

Wordpress is the most popular content management system out there. Central to its success is the ability to extend any of its functionality with plugins. One of these plugins is WooCommerce — A plugin that turns your Wordpress website into a full-fledged online store, and is probably the most popular self-hosted e-commerce solution by date.
Wordpress has a multisite feature, which allows you to host an unlimited number of Wordpress instances with a single Wordpress deployment.

Here are my recommendations for running a Wordpress Multisite network.

Install only the plugins that you really, really need

What is true for standalone Wordpress, is also true for a Wordpress Multisite network: Favor plugins that are stable, popular and above all, actively maintained. When using plugins with strict licensing agreements (i.e. non-FOSS), be aware that some plugin providers require a license per domain or even per Wordpress instance.

Herd your cats with WP-CLI

WP-CLI is a command line utility to manage your Wordpress sites with automation. Manual administration of each site through the Wordpress dashboard can be virtually impossible with a large enough number of sites. With WP-CLI you can list all sites and iterate over them, applying changes to each site in one fell swoop.

mapfile -t site_list < <(wp-cli site list --field=url)
for site in "${site_list[@]}" ; do
  echo -n "$site: "
  # get/set site specific option
  wp-cli option get blogname --user=1 --url="$site"
done

For example, there was a bug in WooCommerce 9.0 that applied the wrong amount of shipping cost. The temporary workaround was very simple, and required only a small configuration change. If you have to fix a hundred sites, WP-CLI will be the tool to use. WP-CLI also has the ability to search and replace one string to another — across all your sites.

Update everything everywhere, all the time

There’s no way around updates — You need to update everything everywhere, all the time. And it has to be automated. When you installed Wordpress and some plugins you implicitly trusted the developers. You just have to trust them a tiny bit more, and hope that their updates don’t break your site. If an update does break your site, consider removing the offending plugin or theme outright. But you have to update everything everywhere, all the time. Create a shell script and put it into your crontab. Make sure you get notified if an update fails.

wp-cli core update --locale=de_DE
wp-cli core language update
wp-cli plugin update --all
wp-cli theme update --all
wp-cli core update-db --network

# some plugins, like WooCommerce, have a wp-cli hook that runs
# maintenance tasks in bulk, to remove pressure on WP cron
for site in "${site_list[@]}" ; do
  wp-cli plugin is-active woocommerce --user=1 --url="$site" && \
    wp-cli wc update --user=1 --url="$site"
done

Default Wordpress Cron is a Hot Mess

The default mechanism in Wordpress for recurring or delayed tasks requires no installation, but is hardly adequate even for a single Wordpress site. I recommend switching to a manually triggered cron. Consider running it every minute.

# example, multisite cron with site-level locking
for site in "${site_list[@]}" ; do
  flockfile=$(echo "$site" | shasum | awk '{ print $1 }')
  flock -n "/var/lock/whatever/$flockfile" \
    wp-cli cron event run --due-now --url="$site"
done

Site provisioning

Create or obtain a plugin that can clone an existing site in your multisite network. This allows you to build Template Sites that are the starting point for new sites you want to create. For example, you could have a fully configured yet empty WooCommerce store ready to be cloned and made into a new site.
Try to automate content creation as much as possible. In my case, I wrote a plugin that loads product data from an external API, and imports them into WooCommerce. WooCommerce’s product import has been exceptionally stable over the years, across many versions.

Miscellaneous

In general, performance improvements that apply to a regular Wordpress install also apply to your Wordpress multisite. For example, always use an object cache, such as redis.
Verify that your database can handle thousands of tables. Depending on the database engine, you might want to check ulimit -n for your database user. Some databases use multiple file handles per table.

Automate everything. Update everything. Have backups. Sleep well.

Last updated on