WooCommerce slows down for predictable reasons: every page that can't be cached (cart, checkout, My Account, AJAX add-to-cart) runs full PHP and hits the database, the admin loads dozens of plugin queries, and product images are often shipped at full resolution. This guide walks through the changes that move the needle most — in roughly the order of impact — with commands you can paste on a Linux server (Nginx + PHP-FPM + MariaDB). The same principles apply on managed hosting; you just toggle the equivalent settings in the control panel.
1. Start with the right hosting stack
A store can't outrun a slow server. Before tuning software, make sure the foundation is sound:
- PHP 8.1+ with OPcache enabled — modern PHP is dramatically faster than 7.x.
- MariaDB 10.6+ / MySQL 8 on local NVMe storage, not a shared, throttled database.
- At least 2 vCPU and 4 GB RAM for a real catalog; checkout is CPU-bound during traffic spikes.
- HTTP/2 or HTTP/3 and a current OpenSSL for fast TLS.
If your store serves Saudi and Gulf customers, hosting inside the Kingdom also cuts round-trip latency and keeps data residency aligned with PDPL and NCA expectations. Skyline Cloud runs in-Kingdom infrastructure built for exactly this — see cloud hosting and our ecommerce hosting guides.
Confirm your versions:
php -v
mariadb --version
php -i | grep -i opcache.enable
2. Add a Redis object cache (biggest single win)
WooCommerce makes the same expensive database queries over and over. A persistent object cache stores their results in memory, so uncached pages (cart, checkout, dashboard) get dramatically faster.
Install Redis and the PHP extension:
sudo apt update
sudo apt install -y redis-server php-redis
sudo systemctl enable --now redis-server
Then install the Redis Object Cache plugin in WordPress and add this to wp-config.php above the "stop editing" line:
define( 'WP_REDIS_HOST', '127.0.0.1' );
define( 'WP_REDIS_PORT', 6379 );
define( 'WP_REDIS_MAXTTL', 86400 );
define( 'WP_CACHE_KEY_SALT', 'mystore_' );
Go to Settings → Redis and click Enable Object Cache. Verify it's connected:
redis-cli info stats | grep keyspace_hits
3. Tune OPcache and PHP-FPM
OPcache keeps compiled PHP in memory so it isn't recompiled on every request. Edit your PHP config (e.g. /etc/php/8.2/fpm/conf.d/10-opcache.ini):
opcache.enable=1
opcache.memory_consumption=256
opcache.max_accelerated_files=20000
opcache.validate_timestamps=1
opcache.revalidate_freq=60
PHP-FPM pool sizing matters under load. A rough rule: pm.max_children = available RAM for PHP ÷ average process size. With ~4 GB free and ~80 MB per worker, around 40 children is sane. In /etc/php/8.2/fpm/pool.d/www.conf:
pm = dynamic
pm.max_children = 40
pm.start_servers = 8
pm.min_spare_servers = 6
pm.max_spare_servers = 12
pm.max_requests = 500
Reload: sudo systemctl reload php8.2-fpm.
4. Page caching for everything that can be cached
Most of your traffic — the homepage, shop, category and product pages — is identical for logged-out visitors and should be served as static HTML. Use a caching plugin (WP Super Cache, W3 Total Cache, or your host's built-in cache) and always exclude the dynamic pages:
/cart//checkout//my-account/- Any URL with the
?add-to-cart=parameter or thewoocommerce_cart_hash/wp_woocommerce_session_cookies.
Serving cart or checkout from cache will leak one customer's basket to another, so confirm these exclusions before going live.
5. Optimize images and assets
Product photos are usually the heaviest part of a page.
- Serve WebP or AVIF and lazy-load below-the-fold images (WordPress lazy-loads natively).
- Resize uploads — a 4000px photo displayed at 600px wastes bandwidth.
- Define sensible thumbnail sizes under Settings → Media and regenerate after changes.
- Minify and combine CSS/JS, and defer non-critical scripts.
You can batch-convert existing images on the server:
sudo apt install -y webp
cd wp-content/uploads
find . -type f -iname "*.jpg" -exec cwebp -q 80 {} -o {}.webp \;
6. Clean and index the database
WooCommerce accumulates expired transients, abandoned sessions, and post revisions. Trim them on a schedule with WP-CLI:
wp transient delete --expired
wp post delete $(wp post list --post_type=revision --format=ids) --force
wp db optimize
Two structural wins for larger stores:
| Change | Why it helps |
|---|---|
| Enable High-Performance Order Storage (HPOS) | Orders move to dedicated tables instead of wp_posts, cutting query bloat |
| Move WooCommerce sessions to Redis | Stops wp_options autoload from ballooning |
Enable HPOS under WooCommerce → Settings → Advanced → Features, then run a few test orders to confirm extensions are compatible.
7. Measure, don't guess
Establish a baseline and re-test after each change. Use the Query Monitor plugin to find slow queries and the worst plugins, and a public tool (WebPageTest or PageSpeed Insights) for real-world load times. From the server, time the uncached checkout path:
curl -o /dev/null -s -w "TTFB: %{time_starttransfer}s\n" https://yourstore.sa/checkout/
Track Time To First Byte before and after. If TTFB is still high after caching, the bottleneck is usually PHP-FPM saturation, a slow plugin, or a remote API call on checkout (payment/shipping) — profile with Query Monitor to find it.
Quick hosting checklist
- PHP 8.1+ with OPcache, MariaDB 10.6+ on NVMe
- Redis object cache enabled and hitting
- Page cache on, with cart/checkout/account excluded
- HTTP/2 or HTTP/3 + valid SSL
- HPOS enabled, database optimized on a cron
- Images served as WebP/AVIF and lazy-loaded
A fast store also needs reliable transactional email so order confirmations and password resets land in the inbox — see business email hosting.
Start on Skyline Cloud
Skyline Cloud gives you in-Kingdom WooCommerce hosting with NVMe storage, modern PHP, one-click SSL, and local Arabic support — tuned for the stack above. Create your account and launch a faster store today.
Comments
0 total · 0 threads