A Guide for Improving WordPress Server Response Time
Server response time is the gap between a visitor clicking a link to your site and their browser receiving the first piece of data back from your...
WooCommerce retailer, 8,000 products, five-figure monthly revenue
Page load time
DB queries per page
The client ran an established WooCommerce store with around 8,000 products. The business was profitable and generating consistent five-figure monthly revenue. Over the course of about six months, page load times had crept from approximately 1.5 seconds to over 30 seconds on product pages.
Their hosting company had repeatedly advised them to upgrade to a larger server plan. They had done so twice. Performance had not improved. The hosting company then advised them the problem was their traffic volume and suggested a dedicated server at significantly higher cost.
The client contacted me before making that purchase. They were correct to do so.
Query Monitor revealed 847 database queries on a single product page load. Most sites of this type should generate between 20 and 60. I began tracing the source of each query cluster.
Three distinct problems were identified:
Unindexed meta query
A plugin installed eighteen months earlier was performing a postmeta lookup on every product page without using an index. At 8,000 products with multiple meta records each, this single query was scanning millions of rows per page load.
N+1 query loop
A customisation in the theme was iterating over related products and executing a fresh database query for each one individually, rather than using a single joined query. On a page with twelve related products, this generated twelve separate queries for data that could have been retrieved in one.
WooCommerce session bloat
The woocommerce_sessions table had grown to 2.3GB. Sessions were never expiring due to a misconfigured cron job. The database engine was taking increasingly long just to open the table for any WooCommerce-related operation.
None of these were hosting problems. A larger server would have reduced the query time marginally. It would not have fixed the root cause.
The work was carried out in a staging environment with a full database clone, then deployed to live in a single maintenance window.
Added a composite index on the offending meta key. The plugin's query went from a full table scan to an indexed lookup — reducing its execution time from ~2,100ms to ~8ms.
Rewrote the theme's related products loop to use a single WP_Query call with the required post IDs, eliminating the N+1 pattern entirely.
Purged the orphaned session records (reducing the table from 2.3GB to 45MB), repaired the broken cron schedule, and set a correct session expiry window.
Implemented Redis object caching at the server level to prevent similar query volume from re-emerging under normal traffic conditions.
Product pages moved from 30+ seconds to under one second. The database query count dropped from 847 to 23. The woocommerce_sessions table stabilised at under 60MB.
The client did not upgrade their hosting plan. They did not need to. The site has not exceeded 1.2 seconds on any monitored page load since the work was completed.
The problem was never traffic. It was three specific, identifiable faults that had accumulated over eighteen months without anyone looking for them properly.
From the blog
Server response time is the gap between a visitor clicking a link to your site and their browser receiving the first piece of data back from your...
Your website going offline is a real operational risk. Servers overload, software conflicts bring sites down, and physical damage to hosting...
When a website goes offline, the loss is immediate. Visitors who cannot reach your site do not wait. They leave, and they spend their money elsewhere....
I diagnose before I fix. You will know exactly what is wrong and what it will cost to resolve before any work begins.