Himanshu SharmaSoftware engineer
Let’s talk

WordPress · Lesson 44 of 45

Making WordPress fast

Speed up WordPress with better hosting and PHP, page and object caching, lean plugins, optimised images and database cleanup, and measure the result.

15 minSecurity, performance and projectUpdated 23 October 2026

By the end of this lessonFind what slows a WordPress page down, apply the changes that make the biggest difference, and measure the result instead of guessing.

Measure first

"Make it faster" is not a plan. Start by finding where the time goes. A page has two halves:

  1. Server time: how long until the first byte arrives (TTFB). It covers PHP, database queries, and plugins. Good is well under 600 ms.
  2. Browser time: downloading and showing images, CSS, JavaScript and fonts.

Browser developer tools (Network tab), PageSpeed Insights and WebPageTest show both. Check a few different pages (the home page, a post, a page with a form) on a mobile connection. Then fix the biggest item first and measure again.

You can measure the server half from the command line too:

bash
curl -o /dev/null -s -w "TTFB %{time_starttransfer}s, total %{time_total}s\n" https://example.com/

1. Hosting and PHP

Cheap shared hosting with many sites on one machine sets the ceiling. Look for:

  • a current PHP version (8.2 or newer); each major release is faster than the last;
  • OPcache enabled, which keeps compiled PHP in memory;
  • HTTP/2 or HTTP/3 and HTTPS;
  • SSD storage, enough memory (256 MB or more per PHP process for WooCommerce-sized sites), and a recent MySQL or MariaDB.
bash
wp eval 'echo "PHP ", PHP_VERSION, "\n";'

The dashboard also shows PHP and database versions under Tools → Site Health → Info.

2. Caching: the biggest win

On every normal request WordPress loads core, loads all active plugins, runs database queries and builds the page with PHP. For a page that looks the same to every visitor, that is wasted work. There are two kinds of cache:

Cache What it saves Typical tools
Page cache the whole finished HTML, served without running PHP host-level caching, or plugins such as WP Super Cache, W3 Total Cache, WP Rocket, LiteSpeed Cache
Object cache the results of database queries and computations, kept in memory between requests Redis or Memcached with a drop-in object-cache.php

A page cache helps public pages enormously; it must skip logged-in users, carts and checkout pages. An object cache helps dynamic pages and the dashboard, and makes transients fast. Browser caching (long Cache-Control headers for static files) and a CDN (a network of servers close to visitors that serves images, CSS and JS) take the load off your server too.

You can see whether an object cache is active:

bash
wp cache type
result
Default

Default means the cache lives only for the duration of one request. With a Redis or Memcached drop-in installed and connected, the command names it.

3. Plugins and themes

Plugins are often the cause of a slow site, but not because of their number: it is what they do on every request.

  • Remove plugins you do not need, and prefer one good plugin to three overlapping ones.
  • Be careful with plugins that load their CSS and JavaScript on every page (see Adding CSS and JavaScript the right way for how to load only where used).
  • Page builders and heavy "multipurpose" themes can add hundreds of kilobytes. A lean block theme loads very little.
  • Avoid plugins that run external HTTP requests during page loads.

To find the culprits, install Query Monitor (a free developer plugin). It shows, per page, the slowest database queries, the plugin or theme responsible for each, slow hooks, HTTP calls, and PHP errors.

4. Images, fonts and scripts

For most sites, images are most of the page weight:

  • Upload images at the size they are displayed, not straight from a camera. WordPress creates smaller versions automatically and writes srcset, so the browser picks the right one.
  • Use modern formats (WebP, AVIF). WordPress can create WebP versions of uploads.
  • Lazy loading is on by default for images below the fold (loading="lazy"); do not lazy load the main image at the top.
  • Set width and height so the page does not jump while loading.
  • Limit custom fonts: two weights of one family is usually enough, served as WOFF2 and hosted on your site.
  • Load JavaScript with defer and only where needed; remove unused ones.
bash
wp media image-size
result
+--------------+-------+--------+------+-------+
| name         | width | height | crop | ratio |
+--------------+-------+--------+------+-------+
| full         |       |        | N/A  | N/A   |
| 2048x2048    | 2048  | 2048   | soft | N/A   |
| 1536x1536    | 1536  | 1536   | soft | N/A   |
| large        | 1024  | 1024   | soft | N/A   |
| medium_large | 768   | 0      | soft | N/A   |
| medium       | 300   | 300    | soft | N/A   |
| thumbnail    | 150   | 150    | hard | 1:1   |
+--------------+-------+--------+------+-------+

The sizes WordPress makes for each upload are listed above. You can regenerate them after changing the theme with wp media regenerate.

5. The database

The database grows with revisions, spam, expired transients and plugin leftovers.

wp db size --tables lists the size of every table. Large tables are usually wp_postmeta, wp_options and the tables of plugins that log data.

bash
wp db query "SELECT option_name, LENGTH(option_value) AS bytes FROM wp_options WHERE autoload = 'yes' ORDER BY bytes DESC LIMIT 5"

That query finds the biggest autoloaded options. WordPress reads every autoloaded option on every request, so a plugin that stores megabytes there slows every page. Look for names you do not recognise; a plugin that has been uninstalled may have left data behind.

Routine cleanup:

  • limit post revisions: define( 'WP_POST_REVISIONS', 5 ); in wp-config.php;
  • empty the trash and delete spam comments (wp comment delete $(wp comment list --status=spam --format=ids));
  • delete expired transients (wp transient delete --expired);
  • optimise tables occasionally (wp db optimize), and take a backup first.
bash
wp transient delete --expired
result
Success: No expired transients found.

6. WordPress behaviour you can switch off

  • Heartbeat pings the server from the editor every 15 to 60 seconds; limit it on small servers.
  • Disable what you do not use, such as emoji scripts or embeds, but only with a clear reason; plugins that do this save a few requests each.
  • Replace WP-Cron triggered by visitors with a real cron job (see Scheduled tasks with WP-Cron).

A short order of work

  1. Measure TTFB and page weight on three pages.
  2. Update PHP and enable OPcache; enable a page cache.
  3. Remove unused plugins; find slow queries with Query Monitor.
  4. Fix images and fonts, then add a CDN.
  5. Add an object cache and clean the database if the dashboard or dynamic pages are still slow.
  6. Measure again and keep a note of what changed the numbers.

Common mistakes

  • Installing three caching plugins at once.
  • Optimising before measuring.
  • Caching pages for logged-in users or checkout pages.
  • Loading huge images and shrinking them with CSS.
  • Never cleaning up after removed plugins.

Exercise

A product page has a TTFB of 2.4 seconds and loads 60 requests. List the first three things you would check, in order.

Show one possible answer
  1. Is the page cached? A TTFB of 2.4 s means PHP builds the page each time. Turn on a page cache (and exclude the cart and checkout pages).
  2. What do the queries and plugins do? Open Query Monitor on the page to find slow queries, remote HTTP calls and the plugin responsible.
  3. Server basics: the PHP version, OPcache, and whether an object cache is available.

Only after the server time is fixed would I look at the 60 requests (images, scripts, fonts).

Key points

  • Measure first: server response time (TTFB) and page weight tell you whether PHP or the browser is the bottleneck.
  • Page caching serves saved HTML without running PHP; an object cache (Redis or Memcached) speeds up database results for logged-in and dynamic pages.
  • Fewer and lighter plugins, a lean theme, properly sized images with lazy loading and a CDN make the biggest front-end difference.
  • Use the Query Monitor plugin and WP-CLI to find slow queries, big autoloaded options, and slow hooks.

Check yourself

1. What does a page cache do?
2. Why can many plugins slow a site down?
3. What does the 'autoload' column of wp_options affect?
4. Which first measurement tells you whether the server or the page is slow?