If you run a growing WooCommerce store, you’ve likely experienced this scenario: you get a notification from your hosting provider warning you of “High CPU Usage.” Your site slows down to a crawl, checkouts stall, and you scramble to figure out why.
This recently happened to our own demo site for Yoohoo Plugins. Our DigitalOcean droplet (running a modest 2GB of RAM and a single CPU core) was routinely spiking above 80% CPU utilization, triggering automated alerts.
Instead of blindly throwing money at the problem by upgrading the server hardware, we decided to look under the hood. What we found was a common, yet easily fixable, architectural bottleneck.
In this post, we’ll walk you through the exact steps we took to optimize our server stack. A huge shoutout and credit goes to the excellent server tuning guidelines from our friends over at Paid Memberships Pro. Their blueprint was the foundation for our success.
The Problem: The “Prefork” Bottleneck

When we connected to our Droplet via SSH to profile the server, we identified the core issue almost immediately: our Apache web server was using the MPM Prefork module, combined with mod_php.
For years, this was the default way to run WordPress. However, it handles traffic synchronously. For every single connection to your website, Apache spawns a heavy, memory-intensive process. When traffic spikes, even slightly from search engine bots or a few concurrent shoppers, your server quickly exhausts its RAM, leading to heavy CPU thrashing as it struggles to keep up.
The Solution: A Three-Pronged Architecture Upgrade
To alleviate the CPU load, we needed to shift the heavy lifting from the CPU to the RAM and optimize how connections were handled. We executed a three-step high-performance hosting strategy.
Step 1: Upgrading to Apache MPM Event and PHP-FPM
The most significant change was ditching MPM Prefork for MPM Event and PHP-FPM (FastCGI Process Manager).
Unlike Prefork, MPM Event handles connections asynchronously. It can manage thousands of concurrent connections using a fraction of the resources. It then passes specifically the PHP execution requests to a dedicated pool of PHP-FPM workers.
To make this switch on our Ubuntu server, we ran the following commands to install the new handler and disable the old ones:
# Install PHP-FPM and the FastCGI proxy module
sudo apt install php8.3-fpm libapache2-mod-fcgid
# Disable the old, heavy modules
sudo a2dismod php8.3 mpm_prefork mpm_worker
# Enable the new asynchronous event module and proxy handlers
sudo a2enmod mpm_event proxy_fcgi setenvif rewrite
sudo a2enconf php8.3-fpm
# Restart the services
sudo systemctl restart apache2 php8.3-fpm
We disabled the old modules and enabled the new architecture. Because our server only had 2GB of RAM, we carefully tuned our PHP-FPM pool (www.conf) to prevent it from consuming all available memory:
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 2
pm.max_spare_servers = 4
pm.max_requests = 500
Note: When configuring max_children, it’s vital to consider your available RAM. We allocated 1GB to MySQL, leaving ~1GB for everything else. By restricting our PHP workers, we ensure that sudden traffic spikes queue up gracefully instead of instantly crashing the server with Out Of Memory (OOM) errors.
Step 2: Tuning MySQL for Memory Efficiency
By default, MySQL on lower-tier servers isn’t configured to use much RAM. If your database buffer is too small, MySQL is forced to read data directly from the disk for every query. This Disk I/O wait time translates directly into high CPU usage.
We updated our /etc/mysql/mysql.conf.d/mysqld.cnf to dedicate a healthy chunk of our 2GB RAM to the MySQL InnoDB Buffer Pool:
[mysqld]
innodb_buffer_pool_size = 1G
max_connections = 150
By dedicating 1GB to the buffer pool, we ensured that the vast majority of our WooCommerce database queries would be served instantly from memory, bypassing the slow disk and saving CPU cycles.
Step 3: The Silver Bullet — Redis Object Caching
WooCommerce pages are notoriously query-heavy. Loading a single product page or generating a cart totals can require dozens—sometimes hundreds—of complex database requests.
Even with a tuned MySQL server, pulling the same data repeatedly wastes processing power. This is where Redis Object Caching shines.
Redis sits in front of your database. When a query is run, Redis stores the result object in memory. The next time a user requests that same data, Redis serves it instantly from RAM, completely bypassing PHP execution and the MySQL database.
We installed the local Redis server on our Droplet:
sudo apt install redis-server php-redis -y
Crucially, to ensure our Redis instance couldn’t be accessed by malicious actors on the internet, we bound it strictly to local connections (127.0.0.1) by editing the /etc/redis/redis.conf file:
sudo sed -i 's/^bind.*/bind 127.0.0.1 ::1/' /etc/redis/redis.conf
sudo systemctl restart redis-server
Finally, we activated the Redis Object Cache plugin directly within our WordPress admin. You can also do this swiftly via WP-CLI:
wp plugin install redis-cache --activate
wp redis enable
The Result: Silence the Alarms

The results were immediate. By changing how the server handled requests, rather than just increasing the server size, we completely eliminated the intermittent high CPU spikes.
Our 2GB Droplet can now comfortably handle significantly more traffic, the administrative dashboard is snappier, and those stressful automated DigitalOcean alerts have finally stopped.
Key Takeaways for Store Owners
- Don’t just upgrade hardware: High CPU is often a software configuration issue. Check your stack first.
- Move away from mod_php: If your host is running Apache with MPM Prefork, look into migrating to PHP-FPM immediately.
- Use Object Caching: For dynamic sites like WooCommerce or Paid Memberships Pro, Redis (or Memcached) is not optional; it’s a necessity for scale.
If you need help optimizing your server or want to add powerful new features to your WooCommerce flow (like automated PDF invoices or Zapier integrations), check out our suite of tools at Yoohoo Plugins.