Skip to main content
Teramont Logo
Slow WordPress Site: 12 Checks to Find the Bottleneck and Speed It Up
Back to Blog

Slow WordPress Site: 12 Checks to Find the Bottleneck and Speed It Up

Mizael Segovia

8/4/2026 ·Mizael Segovia· 15 min read ·

2 views

Direct answer: measure before you optimize

A slow WordPress site is not safely fixed by stacking optimization tools. First measure and separate the layers: DNS and network, time to first byte (TTFB), page cache, PHP and database work, plugins and theme, scheduled tasks, and browser-side work. Then change one variable, repeat the same test, and keep a path back.

This guide provides 12 real checks in that diagnostic order. It does not assume that hosting, a plugin, or WordPress itself is at fault. It also does not promise a universal target: a brochure site, a WooCommerce store, and a private membership area create different loads. The official WordPress performance documentation likewise treats optimization as work across several layers.

What a slow WordPress site actually means

Slow can describe different failures. A high TTFB means the initial response is late, but you still need to separate network delay, a PHP queue, queries, and caching. A poor Largest Contentful Paint (LCP) can come from the hero image, fonts, CSS, or JavaScript even when the HTML arrives quickly; it does not prove that hosting is slow. If only wp-admin is affected, public page cache usually cannot explain it because authenticated sessions commonly bypass that cache. If the slowdown matches imports, backups, or traffic spikes, inspect resources and concurrency.

Page experience combines technical signals and usefulness. Google advises site owners not to reduce it to a single signal or create content primarily for search engines in its guidance on page experience and people-first content. Here, metrics locate a layer; they are not the goal by themselves.

Before changing anything: recovery and a baseline

Confirm that you have a verified backup of both files and the database, preferably off the server, and that you know how to restore it. A dump stored inside the public web root is not a complete external backup and may expose data. Use staging for plugin, theme, or configuration tests. If staging is unavailable, schedule a controlled window, record the initial state, and name the person responsible for rollback.

Build a baseline with two or three representative URLs: a cacheable home or landing page, a post, and an important dynamic view. For WooCommerce, include a product, cart, or account view without placing real orders. Keep region, device, session, and conditions the same, and run several repetitions. Record the date, URL, authentication state, HTTP status, DNS, connection, TTFB, total time, and visual result. The first visit may encounter cold caches while later visits use warm caches. That comparison is more useful than selecting the fastest run.

The commands in this guide are documented procedures, but they were not run on the reader's VPS. Adapt the domain, paths, permissions, and environment, and never paste a command you do not understand. This curl request downloads the response and discards the body. One run is not enough:

curl -o /dev/null -sS -w 'HTTP %{http_code}\nDNS complete %{time_namelookup}s\nTCP connected %{time_connect}s\nFirst byte %{time_starttransfer}s\nTotal %{time_total}s\n' https://example.com/test-page/

From symptom to the next test

SymptomLikely layerNext test
High TTFB when both cold and warmOrigin, PHP, database, or worker queueCompare cache, logs, resources, and a static URL
First visit slow; repeats fastCold cache or dynamic generationInspect headers and the page-cache policy
Reasonable TTFB; late LCPImage, font, CSS, or JavaScriptInspect the waterfall and LCP element
Only wp-admin is slowPlugins, queries, cron, or an external APIUse staging, logs, and scheduled-task data
Slow during backups or importsCPU, memory, disk I/O, or external processesMatch the time window to server metrics
One region is slow and another is notNetwork route, DNS, or CDNRepeat by region and compare origin with edge

The 12 checks

Check 1. Measure TTFB and total time repeatably

Run the baseline several times per URL and retain every result, not just the fastest. time_namelookup, time_connect, time_starttransfer, and time_total are cumulative milestones from the start of the request: DNS completion, TCP connection, first byte, and completed transfer. Do not treat them as isolated phases unless you calculate the differences between milestones. Compare those values with a static URL on the same origin. If the static asset is fast and dynamic HTML is not, the network is no longer the only suspect.

Test as a visitor and, separately, as an authenticated user. Keep the region and protocol constant. Variable TTFB can indicate queueing, intermittent jobs, or caching; steady TTFB still does not explain rendering by itself. The official WordPress optimization guide helps place server, database, and browser resources in one investigation.

Check 2. Review Site Health, versions, and status before adding tools

In Tools → Site Health, record critical issues and recommendations, WordPress and PHP versions, modules, limits, and directory state. Treat the report as evidence, not a verdict. Resolve clear errors first, and confirm compatibility before upgrading. Core implements these tests through WP_Site_Health.

If WP-CLI is available, create a reproducible inventory. These official WP-CLI commands are read-only and capture the inventory plus upcoming jobs without running overdue events:

wp core version
wp plugin list --status=active
wp theme list --status=active
wp cron event list --fields=hook,next_run_relative,recurrence
wp db size --tables --human-readable

Keep the output with the incident or change record, without publishing server paths, usernames, or infrastructure details.

Check 3. Separate cold cache, warm cache, and page cache

Make one request after purging only the cache layer you control, followed by several requests without purging. Inspect headers such as Age, Cache-Control, or a provider-specific cache header, but do not assume every stack uses the same names. A large improvement after the first load suggests a warm cache. Responses that remain dynamic may reflect an intentional exclusion, a cookie, or incomplete configuration.

Page cache stores a full HTML response and can avoid repeated PHP and database work. It is not the same as object cache. WordPress documents both in its caching guide, and Site Health has a dedicated page-cache test. Keep one owner for page caching and a clear purge policy; stacking plugins or layers without knowing their order causes inconsistencies. Cart, checkout, account, and other personalized views must retain their exclusions.

Check 4. Isolate active plugins with a controlled test

Use the plugin inventory to identify code that runs on every request, including security, redirects, analytics, page builders, search, translation, and external API integrations. Review must-use plugins and provider extensions too. Correlation is not enough; you need to observe what changes when one variable is removed.

Do this only in staging or, if there is no alternative, in a controlled window with a backup, suitable maintenance handling, an exact list of active plugins, and rollback ready. Disable one plugin at a time or a reasoned group, repeat the same URLs, and test critical functions. If there is no repeatable gain, restore the original set immediately. Do not experiment blindly in production or leave a store without payments, security, or backups. If you uncover a vulnerability, follow a dedicated response process such as Teramont's note on WP2Shell and WordPress rather than turning a performance investigation into an improvised cleanup.

Check 5. Compare the theme, child theme, and their assets

A theme can add queries, complex templates, fonts, sliders, and script bundles. In staging, record the active theme and child theme, capture the current appearance, and temporarily test a compatible official theme. Repeat the baseline on mobile and key templates. If performance improves, do not conclude that the entire theme is defective. Compare the template, child-theme functions, and assets to narrow the cause.

Rollback means reactivating the original theme and child theme, restoring their settings, and purging only the necessary caches. Do not change the theme and plugins at the same time; that destroys attribution and can alter widgets, menus, or styling.

Check 6. Inspect images, fonts, CSS, JavaScript, and LCP

Identify the LCP element and inspect the browser waterfall. If HTML arrives promptly but the main image starts late, is oversized, or competes with scripts, the bottleneck is in the frontend. Size images for actual use, serve suitable formats where compatible, avoid unnecessary variants, and do not lazy-load the element that should appear immediately without measuring the effect.

Reduce unused font families and weights, inspect render-blocking CSS, and review third-party JavaScript. Make one change per deployment and verify layout, consent, analytics, and accessibility. A minification plugin can help in a specific stack, but it may also duplicate hosting behavior or break execution order. The goal is a simpler waterfall and a repeatably better LCP, not an isolated score.

Check 7. Find long, delayed, or overlapping WP-Cron jobs

WP-Cron is checked on visits, so backups, feeds, emails, synchronization, or cleanup jobs can run at inconvenient times or be delayed when there is no traffic. wp cron event list lets you inspect hooks, the next run, and recurrence without firing them. Avoid diagnostic runners in production without a controlled window because they may execute overdue events. Next, work with the provider or plugin owner to identify which job consumes time and how often. The official reference explains how WP-Cron works.

Do not disable WP-Cron until a system-cron replacement is configured and verified. If you move execution to real cron, document its frequency, user, path, and alerts; prevent overlaps and test email, renewals, and scheduled posts. Rollback must restore the previous trigger if jobs are missed.

Check 8. Measure the database and autoload without blind deletion

Start with table sizes from the WP-CLI inventory and compare them over time. Identify which plugin owns large tables, revisions, sessions, or queues. To measure autoload itself, group rows in the options table by their autoload value; modern WordPress may use states beyond yes and no. This query is read-only, and its size totals are diagnostic rather than a list of rows that are safe to delete:

Does your WordPress site need a more stable environment?

Explore web hosting with WordPress support and resources for sites that need room to grow.

Premium Character
View Web Hosting
wp db query "SELECT autoload, COUNT(*) AS row_count, ROUND(SUM(LENGTH(option_value))/1024/1024, 2) AS mib FROM $(wp db prefix)options GROUP BY autoload ORDER BY mib DESC;"

Autoloaded options are read on many requests; an excessive set can add memory and work, but the total does not identify which row can be removed. The official Options API documentation describes the role of autoload.

Before changing data, create a private directory outside the document root, owned by the account running WP-CLI, and export the database there. Adapt the path and never create it under public_html, htdocs, or www. This local file is not a substitute for a verified off-server backup:

wp db export /srv/wordpress-private-backups/backup-before-performance-changes.sql
chmod 600 /srv/wordpress-private-backups/backup-before-performance-changes.sql

Do not delete options, transients, tables, or rows because their names look obsolete. Identify the owner and dependency, test in staging, and validate restoration. Do not run OPTIMIZE TABLE or repair as routine maintenance either; both require a demonstrated need, a backup, and a controlled window.

Check 9. Decide whether persistent object cache will help

Object cache stores reusable results and objects; a persistent implementation can retain them across requests. Redis or Memcached may reduce repeated work on dynamic sites with recurring queries, but they do not fix heavy JavaScript, oversized images, one-off queries, or an under-resourced origin. They require hosting support, an extension, a compatible drop-in, memory, an eviction policy, and observability.

First confirm repeated database work and review the official persistent object-cache test. Enable one implementation in staging, use provider tooling to measure hits, errors, and memory, and test invalidation after editing content. If it makes results worse, remove its drop-in/configuration and restore the previous layer. Redis is not a universal requirement.

Check 10. Inspect PHP workers, memory, and errors without exposing them

Dynamic responses occupy PHP workers. When all workers are busy, requests queue even if average CPU looks moderate. Match concurrency, queueing, timeouts, and restarts to slow periods. A PHP memory limit applies per process and is not the same as total RAM; raising it without understanding worker count and consumption can increase pressure. There is no universal value because code, traffic, and plan limits differ.

Read private server and PHP logs first. If a WordPress log is necessary, enable it temporarily in staging or during a monitored window. The wp-config.php documentation defines these constants:

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', '/var/log/wordpress/debug.log' );
define( 'WP_DEBUG_DISPLAY', false );

WP_DEBUG_DISPLAY=false keeps errors off the page. First create the log path outside the document root with the minimum ownership and permissions required by the PHP process; the file can still contain paths, queries, or sensitive data. Then disable debugging and securely remove or archive the log. Never leave it public.

Check 11. Correlate CPU, RAM, disk I/O, and external processes

Use control-panel charts or ask the provider for metrics covering the same baseline interval: CPU, memory, I/O wait, disk usage, processes, reached limits, and restarts. Inspect percentiles or time series, not only a daily average that hides spikes. Match each spike to logs and jobs such as backups, scanners, imports, thumbnail generation, search indexing, email, or a noisy neighbor in a shared environment.

Pause or reschedule a process only when you understand its purpose and preserve its coverage. An I/O-heavy backup may move to a quieter time, but deleting backups is not an acceptable optimization. If the site consistently reaches plan limits after code and configuration fixes, you now have evidence for a capacity discussion.

Check 12. Separate CDN, DNS, and network path from the origin

Repeat the same URLs from more than one region and compare DNS, connection, TTFB, and total time. Check resolution, TLS, caching headers, and whether the response came from the edge or origin. Then, with authorization, compare a direct origin route while retaining the correct Host and security. A provider can help without exposing the origin IP publicly.

A CDN can bring assets closer and, when configured appropriately, cache public pages. It cannot by itself repair wp-admin, PHP, slow queries, or personalized endpoints; a bad rule can even serve private or stale content. DNS mainly affects resolution, while network routes can vary by region. Change one rule, preserve the old TTL and configuration, and verify purging, cookies, sessions, and content. A CDN and a VPS are architecture choices, not magic switches.

A safe order for fixes that preserves attribution

  • Save the baseline, inventory, verified backup, and restoration procedure.
  • Fix reproducible errors and compatibility, then measure again before adding a layer.
  • Configure one page-cache system and its exclusions when the page is cacheable.
  • Optimize the identified LCP element and assets, not everything at once.
  • Isolate a plugin or theme in staging and restore the initial state after each test.
  • Change cron and data only with clear ownership, need, and rollback.
  • Add object cache or capacity only when evidence points to queries or saturation.
  • Tune CDN and network behavior after diagnosing the origin, then retest regions.

For every step, record the hypothesis, change, owner, time, result, and reversal. If an improvement does not repeat under the same conditions, it is not yet a conclusion.

When to optimize, upgrade, or migrate

DecisionSufficient signalWhat to validate
Keep optimizingResources have headroom and the bottleneck is attributable to assets, queries, a plugin, theme, or configurationThe fix improves the same test without regressions
Upgrade the planWorkers, memory, or I/O consistently reach limits after optimizationWhich limit increases, observability, cost, and rollback
Migrate platformsThe workload needs isolation, control, or architecture the current environment cannot provideStaging, DNS, email, backups, window, functional test, and fallback

Stay on shared hosting when it handles the workload, caching works, and there is headroom. A larger plan can solve capacity, not inefficient code. A VPS provides isolation and control, but also requires administration; it is not automatically faster. For context, read what a VPS is and how it works. If you need an approachable environment for WordPress sites, review Teramont Web Hosting and compare its current features with the needs revealed by your diagnosis.

Final verification and rollback

Repeat the same URLs, regions, device, and session state. Run several cold and warm passes, and check HTTP status, TTFB, total time, LCP, and errors. Walk through login, editing, forms, search, and—where relevant—product, cart, checkout, account, webhooks, and email. Review logs and metrics over a comparable interval rather than only immediately after deployment.

Define success before the change: less delay in the target layer, correct behavior, and no new errors. If performance worsens, becomes variable, or a function breaks, execute the prepared rollback. Revert exactly that change, restore configuration or snapshot where appropriate, purge only affected layers, and rerun the baseline. Keep the record even when the hypothesis was wrong.

Frequently asked questions

Which cache plugin should I install?

Use one that is compatible with your hosting and has a clear responsibility. First find out whether the server already supplies page cache. Do not stack plugins that minify, cache, or purge the same content; configure one, document exclusions, and measure it.

Why does WooCommerce require extra care?

Cart, checkout, account, sessions, stock, and webhooks are dynamic. Exclude them from page cache as required by the integration, test purchases in staging, and verify invalidation. A fast home page does not prove the transactional flow is healthy.

Why is wp-admin still slow when the public site is fast?

The public page may come from page cache while admin requests run PHP, queries, permission checks, and external calls every time. Inspect plugins, cron, logs, the database, and workers with a test account.

Will a CDN or VPS speed up WordPress?

Only when it addresses the measured layer. A CDN helps with distance and cacheable content; a VPS helps with isolation or control when correctly sized and managed. Neither replaces fixing queries, plugins, or frontend work.

Conclusion

Start today with one public and one dynamic URL: preserve a backup, run several measurements, compare cold and warm behavior, and use the symptom table to choose the next layer. Continue with only one of the 12 checks at a time. That discipline turns “WordPress is slow” into a testable hypothesis, a reversible fix, and an evidence-based hosting decision.

Slow WordPress Site: 12 Checks to Find the Bottleneck and Speed It Up
GeneralWordPressWordPress HostingServer Administration
Did you like this article?Share it:

About the Author

Mizael Segovia

Mizael Segovia

CEO & Desarrollador Full Stack y DevOps en Teramont Host

Keep exploring related guides, news, and analysis.

CTA Pattern

Need Help with Your Server?

Our team is ready to help with any questions or issues you may have.

Contact Us