Site Owner Tips

WordPress page generation time: how to measure it and bring it down

Published

Page generation time is how long your server spends building a page before a single byte reaches the browser. It is measured in PHP and database work, not in images, fonts or JavaScript, and it is the part of your site speed that caching hides rather than fixes.

If a tool has told you your page generation time is high, this article explains what that number actually contains, how to find which plugin is responsible, and what to do about each cause.

What page generation time actually measures

The clock starts when PHP begins executing and stops when the finished HTML is handed to the web server. Inside that window sits every plugin that loads, every database query that runs, every option that autoloads and every external HTTP call your site makes while rendering.

It does not include DNS lookup, TLS negotiation, image downloads, render-blocking CSS or JavaScript execution. Those are front-end concerns and they are measured separately.

The distinction matters because the two are fixed in completely different ways. A front-end problem is solved with compression, lazy loading and fewer scripts. A generation-time problem is solved by making the server do less work, and no amount of minification touches it.

Why this matters

A slow page generation time is the one metric a page cache cannot hide. Cached visitors never see it, but every logged-in visitor, every cart and checkout page, every wp-admin screen and every crawler request pays it in full. It is also a scalability limit: each page being generated ties up a PHP worker for its whole duration, so a slow site serves fewer simultaneous visitors.

Where to see your own number

Several tools report it under slightly different names:

ToolWhat it is called
Query MonitorPage generation time
GTmetrix / WebPageTestTime to First Byte (TTFB), minus network latency
Chrome DevToolsWaiting (TTFB) on the document request
Server access log$request_time in nginx, %D in Apache
Super Speedy Performance AnalysisMedian generation time, tracked per run

TTFB is the closest browser-visible proxy, but it bundles network latency and any edge cache in front of your site, so it flatters a cached page and misleads on a distant one. A server-side measurement is the honest one.

For reading a single request in detail with Query Monitor, including the authentication-cookie trick that lets you measure what a logged-out visitor experiences rather than an admin, see Performance Quick Start Guide: Solving WordPress Performance Problems.

What counts as slow

Generation timeVerdict
Under 500msGood
500ms-1sWorth attention, and it gets worse as the site grows
1-3sBad; visitors feel it on every uncached page
Over 3sDreadful, and something specific is wrong

These apply to uncached requests. Judge wp-admin, cart, checkout and search by the same scale, because those are the pages real customers spend time on.

Common mistake

Testing your home page from a cache and concluding the site is fast. The home page is the most-cached, least-representative page you own. Measure a product page while logged in, a cart page, and a wp-admin list screen.

What makes generation time high

In practice the causes cluster into a short list, and most sites have two or three of them at once.

Database queries that scan instead of seek. WordPress stores most of what it knows about a post in wp_postmeta, a table that grows at roughly your post count multiplied by your custom field count. Queries against it that have no usable index read the whole table. This is the single most common cause on a WooCommerce store.

Queries running inside loops. A template that fetches one row per product in a list of fifty issues fifty queries where one would do. The individual queries look fast; the sum is not.

SQL_CALC_FOUND_ROWS. WordPress uses this to count total results for pagination. It forces the database to build the entire result set in order to count it, then throws all but one page away.

Autoloaded options. Every option marked autoload = yes is read from wp_options on every single request, including AJAX and cron. Plugins that leave large serialised blobs autoloaded make every page slower, not just their own.

Blocking HTTP calls during render. A licence check, a currency lookup or an analytics ping made synchronously while building the page adds its full round-trip to your generation time, and adds the remote server’s downtime to yours.

Too many plugins doing work on pages that do not need them. A plugin that loads its full stack on every request costs you on every request.

Did you know?

Row counts matter more than query counts. Two hundred queries returning one row each is usually fine; four queries returning eighty thousand rows each will exhaust your PHP memory limit and take seconds. Optimise for rows read, not queries run.

Finding which of these is your problem

Guessing is expensive. Deactivating plugins one at a time on a live site is worse. The efficient path is to measure once, with attribution.

Performance Analysis Overview tab: site score and Top 5 insights

Super Speedy Performance Analysis is free and does this without needing anything installed on the server. It profiles your key pages with its own lean profiler, then attributes the SQL time, query counts, rows fetched and memory to individual plugins and to your theme.

The Overview tab gives a site score and the five findings that matter most, each naming the component responsible.

Plugins tab: per-plugin SQL time, query count, rows fetched

The Plugins tab is usually where the answer is. It ranks every plugin by SQL time, query count and rows fetched across the whole analysis, so “the site is slow” becomes “this plugin spends 400ms in the database on every product page”.

The pages tab gives you a league table of your worst performing pages and lets you drill down into what each is doing.

The Pages tab drills into a single page: its slowest queries, which plugin ran each one, and any HTTP calls made during render. Captured queries are put through MySQL’s EXPLAIN afterwards, so a slow query is reported with the reason it is slow – no usable index, a temporary table, a filesort – rather than only the fact that it took a while.

Analyse this page – see specific details for a specific page from the front-end – lets you see inside themes, inside functions, see slow SQL queries and more

The ‘Analyse this page’ option lets you see a detailed breakdown on each specific page giving you total insight into why any page on your website is running slowly.

The checkout flow analysis in Super Speedy Performance Analysis lets you see where all the time is going behind the scenes

The checkout flow analysis creates orders and puts them through your checkout so you can find out what’s happening behind the scenes at the most critical stage of your site – accepting money!

Performance Tip

EXPLAIN runs during analysis, never inside a profiled request, so it cannot distort the measurement it is explaining. It never executes the query either – only the plan is read.

When several plugins look guilty, deep analysis settles it by virtually disabling plugins for test requests only, measuring each suspect’s true cost. Live visitors are never affected.

The History tab records median generation time across runs, which answers the question that matters as a site grows: is this getting worse?

Fixing what you find

Missing indexes on postmeta and friends

The fix is an index that lets the query seek instead of scan. Adding one by hand means knowing which columns, in which order, with which prefix lengths – and getting it wrong costs disk and write speed for no gain.

Scalability Pro carries a curated set of these for the tables WordPress and WooCommerce query hardest: wp_postmeta, wp_posts, wp_term_relationships, wp_term_taxonomy, wp_terms and WooCommerce’s product lookup table. Each is named, so it can be removed again precisely.

Typical result

On a 2.03 million row wp_postmeta table, the SELECT DISTINCT meta_key probe that WordPress’s custom-fields metabox runs went from a 950ms full table scan to a 1.4ms index scan.

SQL_CALC_FOUND_ROWS

Scalability Pro can replace the count with a cheaper equivalent, so pagination still works without building the full result set to count it.

Autoloaded options

Find the large ones and stop them autoloading. The Managing the wp_options Table and Autoload article covers how to identify them safely and which are safe to change.

Queries in loops, and plugins doing work they need not

These are plugin-specific and the analysis names the culprit. Sometimes the answer is a setting, sometimes a lighter alternative, sometimes a support ticket to the plugin author with the evidence attached – which the analysis gives you in a form they cannot dismiss.

The whole class of problem

The reason the two plugins work well together is that they solve different halves. The analysis identifies causes with evidence; Scalability Pro carries fixes for the common ones so they do not have to be built by hand.

Best for
  • WooCommerce stores where uncached pages, cart and checkout feel slow
  • Sites where wp-admin has become painful to use
  • Any site whose database has grown past a few hundred thousand postmeta rows
  • Anyone who has been told “your TTFB is high” and does not know why
Don’t use this if
  • Your problem is images, fonts or JavaScript – that is front-end work, and a different article
  • Your site is small and fast and you are optimising out of habit
  • You have not measured yet – start with the analysis, not with a fix

Common mistakes

Adding a page cache and calling it fixed. Caching hides generation time from anonymous visitors. Logged-in users, carts, checkouts and wp-admin still pay it, and those are the pages that make you money.

Adding indexes speculatively. Every index costs disk and slows writes. Add the ones your own slow queries need, which means measuring first.

Optimising the home page. It is usually the fastest page you own and the least representative.

Chasing query count. A page running 300 fast queries is often healthier than one running 6 that each read 50,000 rows.

Comparing TTFB across tools. Different tools measure from different places with different network paths. Compare a number only against itself over time.

Frequently asked questions

Is page generation time the same as TTFB? No. TTFB includes network latency and any edge cache in front of your site. Page generation time is purely server-side work. TTFB is a reasonable proxy when measured from a consistent location, but it is not the same number.

Does a page cache fix a slow generation time? It hides it for anonymous visitors on cacheable pages. Cart, checkout, wp-admin, and every logged-in session still pay it in full.

Why is wp-admin slower than the front end? Admin screens run list tables, counts and meta queries that the front end does not, they are never page-cached, and every plugin loads its admin code. The same diagnosis applies.

My host says the server is fine. Who is right? Both, usually. Generation time is dominated by what your PHP and database are asked to do, not by how fast the hardware is. A faster server makes bad queries less bad; it does not make them good.

How much can I expect to gain? It depends entirely on the cause, which is why measuring first matters. A missing index on a large wp_postmeta can be the difference between a second and a few milliseconds. A front-end problem misdiagnosed as a back-end one gains nothing.

Further reading

the broader diagnostic path if generation time is only part of your problem
what the fixes actually do

Comments

▲
▼
1/1