WooCommerce Performance Optimizations

While SpinupWP already performs several performance optimizations for you, see Why Is My Site so Much Faster on SpinupWP?, there are still several approaches and strategies to consider when optimizing a WooCommerce store. Due to how vastly different WooCommerce stores can be, some of these performance optimizations may or may not apply to you, and that’s okay. Not all of these performance optimizations are meant to be taken as set in stone or to be applied in general.

With that out of the way, let’s begin by assessing the store.

Assessing Your Store

Before performing any performance optimizations, you must first understand your store.

  • How large is your product catalogue (e.i., how many products are you looking at selling)?
  • How large is your target demographic?
  • How much traffic are you expecting on any given day?
  • How much traffic are you expecting during a sale or marketing campaign?
  • What sort of needs must your store fulfill (in terms of functionality)?
  • How many and what sort of customizations will you require to fulfill those needs?

These are just a couple of questions you must answer in order to begin optimizing your WooCommerce store.

Choosing the Right Server Spec

When it comes to WooCommerce performance, choosing the right server spec is crucial to ensuring that your store runs smoothly, especially as it grows. The server you choose needs to be able to handle the specific demands of your store, from the size of your product catalogue to the amount of traffic you expect during peak times. Just as with performance optimizations, the right server spec can vary greatly depending on your store’s unique needs. Below are some factors to consider when selecting your server.

CPU (Central Processing Unit): The CPU is the brain of your server. More powerful CPUs (with more cores and higher clock speeds) can process requests faster, which is especially important during high-traffic events or when running resource-heavy customizations. Look for CPUs with higher single-core performance, as PHP processes (like those running WooCommerce) benefit from this. Additionally, consider using Dedicated CPU cores whenever possible, as these will provide your store with more consistent performance as opposed to shared ones. In terms of core count, a 2 cores CPU should be a good starting point for small stores, though larger stores should consider 4 cores or more depending on dynamic customizations and traffic.

RAM (Random Access Memory): Sufficient RAM ensures that your server can handle multiple requests simultaneously without slowing down. WooCommerce stores with larger product catalogues or high traffic will require more RAM to avoid performance bottlenecks. In terms of amount, based on a PHP memory_limit of 256MB (recommended by WooCommerce) and pm.max_children of 8 (more on that later), 4GB of RAM should be a good starting point for small stores, though larger stores should consider 8GB of RAM or more depending on database and object cache usage (which can significantly increase during a marketing campaign or sale).

Storage: When it comes to storage, most modern hosting providers now offer SSD (Solid State Drive) storage by default, which is a significant improvement over traditional HDD (Hard Disk Drive) technology. As such, your main concern here is the amount of storage. Of course, this can vary between stores, but 50GB of storage should be a good starting point for a small store. Larger stores will require more storage, obviously, but the amount of storage will largely depend on the site’s media (images, videos, etc.) and database (product listings, orders, payment information, etc.).

Bandwidth and Network Speed: Depending on your expected traffic, you may need to consider server bandwidth and network speed. High traffic stores, or those with global customers, will need faster network connections to handle larger volumes of data transfer. This is especially important for stores whose database is hosted in an external database service provider, as the web server becomes reliant on a good network connection with low latency to the database service provider to send and receive database queries in a timely fashion.

Tuning PHP-FPM

We’ve gone over this topic previously in our Understanding PHP Pools and How do PHP Workers Impact WordPress Performance? docs, so for the purposes of this doc and to avoid repeating ourselves, we won’t go too deep into details and instead focus solely on WooCommerce specific adjustments that you can do to optimize your store’s performance.

By default, SpinupWP utilizes the following PHP and PHP-FPM settings when deploying your sites:

PHP

max_execution_time = 30
max_input_vars = 1000
memory_limit = 128M
post_max_size = 64M
upload_max_filesize = 64M

PHP-FPM

pm = dynamic
pm.max_children = 5
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_spare_servers = 1

Note: These are not all the settings present in each configuration file, but they are the most relevant in regards to performance.

While these settings might suffice for regular sites that use our page caching, WooCommerce stores would quickly report a variety of issues stemming from a lack of PHP workers, available memory for said workers, and PHP script timeouts. As such, we’ll go over all of these settings under the assumption that your server’s specifications match our recommended minimum for WooCommerce, mentioned in the previous section and, for clarity, listed below:

CPU: 2 cores
RAM: 4GB
Storage: 50GB

Recommended Values for PHP Settings

  • max_execution_time: While you may feel compelled to increase this value as high as possible, consider that max_execution_time controls how long your PHP scripts can run for, and it also functions as a failsafe against memory leakage. Since a script would only be able to run for a given amount of time, after which, it will be killed. On the other hand, starving your PHP scripts from enough execution time can cause issues on your pages and plugins, most commonly, 504 errors.

    As you can see, there’s not a silver bullet value that we can recommend for this setting. However, we can provide you with some guidelines as to what you may need to consider when adjusting your max_execution_time. For instance, as a starting point, we recommend taking a look at your page builder’s documentation and searching for its system requirements, as page builders usually recommend certain PHP values that work best for them, max_execution_time among them. On the other hand, if you don’t use a page builder, then we would recommend scanning your plugin list for heavy loaders and looking at their documentation to see what they recommend.

    Ultimately, your max_execution_time value should accommodate the heaviest plugin or task in your WooCommerce store.

    Lastly, it is also worth mentioning that your max_execution_time value should match your fastcgi_read_timeout value (by default, 60 seconds) in your Nginx configuration (/etc/nginx/nginx.conf), as you don’t want Nginx cutting the connection off before your PHP scripts finish running.

  • max_input_vars: Perhaps the most obscure setting on our list, we typically don’t recommend changing this setting unless you have a problem with it. Since max_input_vars is responsible for the amount or variables a GET and POST requests can have as well as cookies. It also, as per PHP’s documentation, mitigates the possibility of denial of service attacks made by hash collisions.

    Hence, why we recommend adjusting this setting on a case-by-case basis instead.

  • memory_limit: Probably the most well known setting on this list, memory_limit is responsible for keeping each of your PHP workers in check by making sure they don’t consume more memory than they should. Similar to max_execution_time, it also functions as a failsafe against memory leakage, for which reason we don’t recommend going overboard with it.

    That said, unlike max_execution_time, we can definitely recommend hard figures for this setting. By default, memory_limit is set to 128M, which is fine for most sites. However, WooCommerce’s documentation alludes to a recommended 256M, which we agree as a healthy starting point.

    Nevertheless, similarly to max_execution_time, it’s important to consider the rest of your plugins and look at their documentation when adjusting this setting, as your memory_limit should aim to accommodate your store’s heaviest plugin, theme, or task.

  • post_max_size: Tied to PHP’s memory_limit directive, post_max_size defines the maximum size of POST data that can be submitted to the server. This includes your site’s forms, file uploads, and any other data sent via a POST request. It is also important to keep in mind that post_max_size operates within PHP’s memory_limit, and also shares its space with upload_max_filesize.

    For which reason, we recommend setting the value of post_max_size to half of your memory_limit. That way, you leave enough space for upload_max_filesize to operate comfortably, while also leaving enough space for your PHP scripts to store things on RAM.

  • upload_max_filesize: Likewise to post_max_size, upload_max_filesize is also tied to PHP’s memory_limit directive, and its main function is to control the maximum size of files that can be uploaded to the server. Also, similarly to post_max_size, upload_max_filesize directly impacts the functionality of the Media Library and file upload forms.

    We recommend setting the value of upload_max_filesize to half of your memory_limit. That way, you leave enough space for post_max_size to operate.

Recommended Values for PHP-FPM Settings

  • pm: The pm directive defines how PHP-FPM manages its worker processes. It has 3 available modes: dynamic, ondemand, and static. By default, SpinupWP uses dynamic mode when spinning up sites, and while this mode is perfectly fine for regular sites, it can be detrimental to WooCommerce stores in terms of performance. We won’t go into too many details as to why that is, but the gist of it is this, dynamic mode can create significant performance overhead on highly dynamic sites, like WooCommerce stores, this means worker processes are quickly spawned and killed to satisfy the demand of the store, which is not ideal, as this is very inefficient.

    Instead, we recommend setting pm to static mode, as this mode keeps the worker processes always active and ready to handle incoming requests, cutting out the inefficiencies of always spawning and killing worker processes.

  • pm.max_children: This setting determines the maximum number of worker processes PHP-FPM can spawn. Though you may feel compelled to increase this value as high as possible, keep in mind that each worker process is bound to your PHP settings. This is specially relevant when taking into account PHP’s own memory_limit, as each worker process will be limited by the same amount of memory. Thus, it is very easy to starve out your server from available memory (RAM) if an excessive amount of worker processes is generated, as it can lead to a server crash.

    Before we begin to calculate a suitable value for pm.max_children, first, it is important to understand that your server is not just running PHP. It is also running a variety of background services that are important for the Linux kernel to work properly, not to mention the other services that your store will directly depend on, such as Nginx, Redis, and MySQL (unless using an external database). Therefore, let us start by assessing our server’s resources and system requirements.

    Using our recommended minimum server specifications listed earlier as a baseline, 4GB would be our server’s total amount of RAM. However, since Ubuntu Server requires a minimum of 1GB of RAM to function, see Ubuntu Server’s System Requirements, that leaves us with effectively 3GB of RAM to work with. Thus, we must now divide our RAM accordingly to accommodate MySQL, PHP, and Redis.

    MySQL and Redis’ RAM usage will be highly dependent on the amount of activity generated by your store. As such, let’s reserve 1GB of RAM for both to share as a starting point, which leaves us with 2GB of RAM for PHP to work with. Finally, let’s calculate the amount of worker processes that our server can handle for our store, based on the amount of RAM left available for PHP:

    pm_max_children (8) = RAM dedicated to PHP (2048M) / memory_limit (256M)
    

    It is important to understand that this is a very conservative calculation, since we’re assuming the worst case scenario for your store (for example, during a big sale), in which all your worker processes will be at 100% capacity all the time. In practice, your store will likely have periods of low traffic followed by high traffic spikes, in which your worker processes will barely use any memory. Nevertheless, we would still recommend the above formula when running your pm.max_children calculations, as it will produce a very safe starting point that won’t result in a potential memory overload for your server.

Keeping Plugins to a Minimum

One of the simplest yet most effective ways to optimize the performance of your WooCommerce store is to minimize the number of plugins you use. While plugins can add valuable functionality to your site, each one introduces additional code that must be loaded, executed, and maintained, which can have a significant impact on your store’s performance.

Why Too Many Plugins Can Be a Problem

Each plugin you install can:

  • Add more database queries, increasing load times.
  • Consume more server resources, such as CPU and RAM.
  • Create potential conflicts with other plugins or your theme.
  • Require updates and security patches, increasing maintenance overhead.

This is especially critical for WooCommerce stores, which are already resource-intensive due to dynamic content, shopping cart sessions, and other e-commerce features.

How to Keep Plugins to a Minimum

Audit Your Current Plugins

Go through your list of installed plugins and evaluate whether each one is absolutely necessary. If a plugin isn’t actively contributing to your store’s core functionality or improving the user experience, consider removing it.

Prioritize Quality Over Quantity

Instead of using multiple plugins to achieve similar goals, look for a single, well-coded plugin that offers all the features you need. For example, choose an all-in-one SEO plugin instead of separate plugins for XML sitemaps, meta tags, and breadcrumbs.

Check Performance Impact

Use tools like Query Monitor or New Relic to identify plugins that are consuming the most server resources. Plugins that cause excessive database queries or API calls should be reevaluated or replaced.

Avoid Redundant Functionality

Avoid installing plugins for features that can be easily achieved through custom code or are already built into WooCommerce or your theme. For instance, simple CSS adjustments or custom post types can often be added via your theme’s functions.php file rather than requiring a plugin.

Regularly Review Plugin Usage

E-commerce needs can change over time. Periodically review your plugins to ensure they still serve a purpose. Deactivate and delete any plugins you no longer need to prevent bloat and potential security vulnerabilities.

Keeping Your Database Clean

A clean and optimized database is critical for maintaining the performance of your WooCommerce store. Over time, your database can accumulate unnecessary data, such as expired transients, spam comments, post revisions, and abandoned carts. This clutter can slow down queries, increase backup times, and consume valuable storage space.

Why a Clean Database Matters

WooCommerce relies heavily on the database to store critical information like product data, customer details, and order records. As your store grows, database performance can become a bottleneck, particularly during high-traffic periods. By keeping your database clean and optimized, you can:

  • Reduce query execution times.
  • Free up server resources like RAM and CPU.
  • Improve the overall speed and responsiveness of your store.

How to Keep Your Database Clean

Regularly Remove Unused Data

Use tools like Advanced Database Cleaner or WP-Sweep to clean up unnecessary data, such as:

  • Expired transients.
  • Revision of posts and pages.
  • Spam or trashed comments.
  • Orphans metadata.

These tools make it easy to identify and remove unnecessary data without impacting your store’s functionality.

Optimize Database Tables

Over time, database tables can become fragmented, which can slow down queries. You can use plugins like Advanced Database Cleaner or WP-DBManager or database management tools like phpMyAdmin to optimize your tables.

Archive Old Orders

WooCommerce stores often retain all orders, including completed and refunded ones, which can bloat the database. Consider archiving older orders that you no longer need for day-to-day operations. There are plugins available that can help you move old orders to a separate table or export them for long-term storage.

Limit Revisions and Autosaves

By default, WordPress saves multiple revisions of your posts and pages, which can quickly add up in the database. Limit the number of revisions stored by adding the following line to your wp-config.php file:

define('WP_POST_REVISIONS', 5);

You can also adjust the autosave interval to reduce the frequency of autosave entries.

Monitor and Maintain Database Health

Regularly monitor your database’s health and performance using tools like Query Monitor or New Relic. Keep an eye on slow queries, and address them by optimizing your database structure or indexing.

Mind Your Cookies

Cookies play a vital role in the functionality of any WooCommerce store, enabling features such as shopping carts, user sessions, and personalized experiences. However, if not managed properly, cookies can also become a source of performance issues and compliance challenges, especially as your store scales.

Why Cookies Matter

In a WooCommerce store, cookies are used to:

  • Track user sessions and maintain cart contents.
  • Store login information for registered customers.
  • Power personalization features like recently viewed products.
  • Enable analytics and marketing tracking.

However, while these are indeed essential functions, excessive or poorly managed cookies can hinder your site’s performance by interfering with our page cache. As Nginx, by design, is unable to serve cached responses to pages with cookies.

How to Manage Cookies Effectively

Audit Your Cookies

Regularly review the cookies set by your WooCommerce store, as well as any third-party plugins or scripts. Tools like your browser’s developer tools or CookieYes’ Advanced Cookie Scanner can help you identify all cookies in use. Ensure that each cookie serves a necessary purpose for your store.

Minimize Cookie Usage

Avoid setting cookies for non-essential features. For example, instead of relying on cookies for simple personalization, consider using server-side sessions or caching mechanisms where appropriate.

Set Appropriate Expiration Times

WooCommerce and related plugins often set cookies with unnecessarily long lifetimes. Review the expiration times of your cookies and adjust them to suit your store’s needs. For example, session cookies used for carts can expire after a few hours, while analytics cookies might have a longer lifespan.

Object Cache Pro

While SpinupWP already provides your sites with object caching, see our Caching in SpinupWP and WordPress Caching: All You Need To Know docs, we think it’s important to discuss Till Krüss’ Object Cache Pro plugin as a premium options that, unlike ours, offers specialized features designed to meet the demands of large, dynamic WooCommerce stores.

For small to medium sized stores, our object caching solution will work perfectly fine, however, once your store starts dealing with thousands of products, you’ll start noticing some performance hiccups as your store reaches the ceiling of our object caching implementation. Therefore, if your store is quite large, we would recommend looking into Object Cache Pro as an alternative solution to object caching.