Quick answer: If your site is slow on a good host, the cause is almost always on the site itself, not the server. The usual culprits are a heavy theme or too many plugins, uncompressed images, missing page caching or CDN, render-blocking JavaScript and CSS, a bloated database, and third-party embeds. Measure first: a slow Time to First Byte (TTFB) points at the server, PHP or the database. A fast TTFB with a slow page points at what the browser has to download. Fix in that order.

Measure before you change anything

"Slow" means different things. A visitor feels slow when the page stays blank, when the main image appears late, or when the page jumps around while it loads. Each has a different cause, so take a baseline before you install another speed plugin.

Run three tests and save the results:

  • Google PageSpeed Insights (pagespeed.web.dev). Look at the field data at the top first. That is real Chrome users over the last 28 days, and it is what Google uses. The lab score underneath is a single simulated mobile load on a throttled connection. It is useful for diagnosis, but don't chase it as a number.
  • WebPageTest or GTmetrix. Both give you a waterfall: every file the page requests, in order, with timings. The waterfall is the most useful view in this whole guide.
  • A plain TTFB check from the command line. It ignores the browser completely and tells you how long the server takes to start answering.
curl -o /dev/null -s -w "DNS: %{time_namelookup}s\nConnect: %{time_connect}s\nTLS: %{time_appconnect}s\nTTFB: %{time_starttransfer}s\nTotal: %{time_total}s\n" https://example.com/

Run it five or six times, because the first request often misses the cache. If TTFB stays well above roughly 0.6–0.8 seconds on a simple page, start with the server-side sections below (caching, database, shared resources, DNS). If TTFB is low but the page still feels slow, the problem is what the browser downloads and runs, so start with themes, images, render-blocking files and embeds.

Keep the test conditions the same each time: the same URL, the same test location, mobile vs desktop noted. Change one thing at a time and retest. Otherwise you will never know which change helped.

Bloated themes and plugins

Multipurpose themes and page builders load CSS and JavaScript for every feature they offer, such as sliders, animations, icon fonts and mega menus, on every page, whether you use them or not. Plugins add more: each one can enqueue its own files and run database queries on every request.

Plugin count alone is not the problem. Twenty small, well-written plugins can be lighter than one heavy one. What matters is what each plugin does on the front end and in PHP.

Self-check

  • In your waterfall, filter by JS and CSS. Count the files and note which folders they come from (/wp-content/plugins/name/ tells you exactly who loaded them).
  • Install the free Query Monitor plugin (WordPress). Load a slow page while logged in and open its panel. Check Queries by Component to see which plugin runs the most and slowest queries, and Scripts / Styles to see what each page loads.
  • In Chrome DevTools, open the Coverage tab (Ctrl/Cmd+Shift+P → "Coverage"), reload, and look at the "unused bytes" column. It is common to see most of a theme's CSS go unused on a given page.
  • On a staging copy, deactivate plugins one at a time and re-run the curl TTFB command and a waterfall test.

Fix

Remove plugins that duplicate each other, such as two SEO plugins or a security plugin plus your host's firewall. Replace a slider with a static image; sliders are among the heaviest elements and rarely get clicks past the first slide. If you use a page builder, turn on its own "improved asset loading" or "performance" options, which most now ship with. If the theme itself is the problem, a lightweight block theme is usually a bigger win than any optimization plugin.

Unoptimized images

Images are usually the largest bytes on a page. The classic mistake is uploading a 4000-pixel, 3 MB camera photo and displaying it in an 800-pixel column. The browser still downloads all of it.

Self-check

  • In PageSpeed Insights, look for "Improve image delivery" (older reports: "Properly size images" and "Serve images in next-gen formats"). It lists each image and the estimated savings.
  • In the waterfall, sort by size. Any single image over about 200–300 KB deserves a look.
  • Find the Largest Contentful Paint (LCP) element in PageSpeed Insights. It is often the hero image. Check that it is not lazy-loaded; lazy-loading the LCP image delays it.

Fix

  • Resize before upload to the largest size actually displayed (often 1600 px wide for full-width images, less for content images).
  • Serve WebP or AVIF. Most image plugins and many hosts' optimizers convert automatically.
  • Always set width and height attributes so the layout doesn't shift while images load.
  • Lazy-load images below the fold, and give the hero image fetchpriority="high" instead.
<img src="/hero-1600.webp" width="1600" height="900"
     alt="Product dashboard" fetchpriority="high">

No page caching or CDN

Without page caching, a WordPress or PHP site rebuilds every page for every visitor: it starts PHP, loads plugins, queries the database and assembles HTML. Page caching stores the finished HTML and serves it directly, which is usually the single biggest TTFB improvement available. A CDN then serves static files (images, CSS, JS) from locations closer to the visitor.

All three hosts compared below include server-level caching and a CDN option on their shared plans, but "included" is not the same as "switched on and configured for your site".

Self-check

  • Check the response headers for a cache status:
    curl -sI https://example.com/ | grep -iE "cache|x-proxy|x-litespeed|cf-cache|age"
    Headers such as x-litespeed-cache: hit, x-proxy-cache: HIT or cf-cache-status: HIT mean the page came from cache. MISS on every repeat request means caching is off, bypassed, or being broken by a cookie.
  • Compare TTFB logged in and logged out. Logged-in users normally bypass the page cache, so a fast logged-out TTFB with a slow logged-in one is expected. Slow in both cases is not.
  • In the waterfall, check where static files are served from. A CDN hostname or CDN response headers on images, CSS and JS confirm the CDN is active.

Fix

Turn on the host's own caching layer first, using its plugin or control-panel switch. It is integrated with the server and usually beats a generic plugin. Don't stack two page-cache plugins. Exclude only what must be dynamic, such as cart, checkout and account pages.

Render-blocking scripts and styles

When the browser meets a normal <script> or stylesheet in the <head>, it stops rendering until that file has been downloaded and processed. Ten such files, some from other domains, can leave the screen blank for seconds even when the server answered instantly.

Self-check

  • PageSpeed Insights flags this as "Render-blocking requests" (older: "Eliminate render-blocking resources") with a list of files.
  • In the WebPageTest waterfall, look at the green "Start Render" line. Everything to its left that is CSS or JS is holding up the first paint.
  • Look for JavaScript that runs for a long time (the "Reduce JavaScript execution time" and "Total Blocking Time" audits). That hurts responsiveness (INP) after the page appears.

Fix

  • Add defer to scripts that don't need to run before the page shows (most of them).
  • Load fonts with font-display: swap, use fewer weights, and host them locally if possible.
  • Use your caching or optimization plugin's "remove unused CSS" or "critical CSS" feature carefully, and test key pages afterwards. These features can break layouts.
<script src="/js/menu.js" defer></script>

Database bloat

Over time a WordPress database collects post revisions, expired transients, spam and trashed comments, and leftover tables from plugins you deleted long ago. The bigger problem is usually autoloaded options: data that WordPress loads on every single request. When plugins store large blobs there, every page pays the cost before caching even comes into play.

Self-check

  • Query Monitor's Queries panel: sort by time and look for slow or duplicate queries, then see which component runs them.
  • WordPress Site Health (Tools → Site Health) warns when autoloaded options are unusually large.
  • If you have phpMyAdmin or WP-CLI, measure autoload size directly:
wp db query "SELECT SUM(LENGTH(option_value)) AS autoload_bytes FROM wp_options WHERE autoload IN ('yes','on','auto','auto-on');"
wp transient delete --expired

Fix

Back up first. Then limit revisions (define('WP_POST_REVISIONS', 10); in wp-config.php), clear expired transients, empty spam and trash, and remove tables left by uninstalled plugins. If one plugin is responsible for most of the autoload size, deal with that plugin rather than cleaning up after it every month. Object caching, which all three hosts below list on their plans, also helps busy dynamic pages.

Third-party embeds and tags

Chat widgets, YouTube embeds, social feeds, A/B testing tools, heatmaps, ad scripts and several analytics tags all load from other companies' servers. You can't cache them or make their servers faster, and each one adds DNS lookups, connections and JavaScript.

Self-check

  • In PageSpeed Insights, open the "Reduce the impact of third-party code" audit (or the third-party filter in the newer insights). It groups cost by provider.
  • In the WebPageTest waterfall, count the distinct domains. Then use the "Block" option to rerun the test without a given domain and compare.
  • Check Google Tag Manager for tags nobody remembers adding.

Fix

Remove tags you no longer use. Replace a YouTube embed with a thumbnail that loads the player on click (a "facade"). Load chat widgets after user interaction or a few seconds' delay. Keep one analytics tool unless you have a real reason for two.

Shared resource contention

Here the host can genuinely be the cause. On shared hosting your account has CPU, memory, process and I/O limits, and you share the physical server with other accounts. If your site hits its limits during traffic peaks or a cron job, requests queue and TTFB climbs even with caching on. Uncached traffic such as logged-in users, WooCommerce carts, search pages and bots hits those limits fastest.

Self-check

  • Open the resource-usage page in your control panel (cPanel "Resource Usage", Hostinger hPanel's resource usage view, SiteGround Site Tools statistics) and look for CPU, entry-process or memory limits being hit, especially at the times visitors complain.
  • Run the curl TTFB command at different times of day. Consistently fine off-peak but slow at peak points at limits or contention.
  • Check your access logs or security plugin for bot traffic. Aggressive crawlers can consume a shared plan's limits on their own.

Fix

First reduce uncached work: caching, blocking abusive bots, and moving WP-Cron to a real server cron. If you still hit limits regularly, the honest answer is a bigger plan or cloud/VPS hosting. That is the point where comparing hosts on resources and renewal price actually matters (see our comparison table).

DNS and TTFB

Before the first byte can arrive, the visitor's browser has to look up your domain (DNS), open a connection and negotiate TLS. Slow DNS providers, long CNAME chains, or a server on a different continent from your audience add delay to every first visit, and no WordPress plugin can fix that.

Self-check

  • Look at the DNS, Connect and TLS lines from the curl command in section 1. DNS consistently above roughly 100 ms is worth investigating.
  • Check your records and how many hops resolution takes:
    dig example.com +trace
    dig www.example.com CNAME +short
    nslookup example.com 1.1.1.1
  • Use a global DNS propagation or lookup tool (for example DNSChecker or Google's dig tool in Admin Toolbox) to see response times from several regions.
  • Run WebPageTest from a location near your audience and one far away. A large gap in TTFB suggests server location matters for you, and a CDN or a closer data center will help.

Fix

Use a fast, well-known DNS provider (your host's, your registrar's premium DNS, or a CDN's DNS). Avoid unnecessary CNAME chains on the root domain. Choose a data center near most of your visitors when you sign up. Most hosts let you pick, and SiteGround, Hostinger and Bluehost all state this on their plan pages. Enable HTTP/2 or HTTP/3 and keep TLS up to date, which most modern hosts do by default.

What SiteGround, Hostinger and Bluehost include

If you've worked through the list and TTFB is still poor, compare what the host actually provides. The table below uses only what each provider states on its own shared hosting page, checked on October 14, 2026. We have not added speed numbers, because a host's "fastest" claims depend on their test setup, not yours.

Feature (shared plans)SiteGroundHostingerBluehost
Built-in caching"Multilevel caching" on all plans (SuperCacher); Speed Optimizer plugin for WordPressLiteSpeed caching; Object Cache listed for WordPress"Static Content Caching" and "Object Caching" listed on Starter and up
CDNFree CDN on all plans (170+ locations stated)CDN listed on Premium; "CDN included" on higher plans"Free CDN" listed on all shared plans
Web server / stackGoogle Cloud infrastructure, custom PHP and MySQL setupLiteSpeed servers, NVMe storage on higher plansNVMe SSD storage; LiteSpeed mentioned for WordPress hosting
Data center choiceYes, at signupYes, at setupYes, at checkout
StagingGrowBig and GoGeekHigher plansListed on Starter and up
Our reviewSiteGround reviewHostinger reviewBluehost review

Sources: siteground.com/web-hosting.htm, hostinger.com/web-hosting, bluehost.com/hosting/shared, all accessed October 14, 2026. Plans and features change, so check the provider page before buying.

The practical takeaway: all three include the caching and CDN pieces this guide relies on. If your site is slow on any of them, check first that those features are actually turned on, then work through the site-side causes above before assuming you need to switch.

The order we would fix things in

  1. Measure: PageSpeed Insights field data, one waterfall, curl TTFB five times.
  2. Make sure page caching is on and returning HITs, and enable the CDN.
  3. Fix the LCP image and resize or convert the heaviest images.
  4. Defer non-critical JavaScript and remove unused plugins or tags.
  5. Clean the database and check autoload size.
  6. If TTFB is still slow at peak times, check resource limits and DNS, and only then consider a bigger plan or a different host.

Is your host the problem?

If TTFB stays slow with caching on and the site trimmed down, or you keep hitting resource limits, the host or plan is the bottleneck. Compare intro and renewal prices and what each plan includes: all hosting reviews · side-by-side comparison · best WordPress hosting.

Ready to compare hosts?

Five hosts scored on the same five factors, with intro and renewal prices side by side.

Compare hosts Read the reviews