How to Tell If Slow Site Is Your Host or Your Code

How to Tell If Slow Site Is Your Host or Your Code

The short answer is that you can usually tell whether your hosting is slow or your website is slow by measuring where the time goes, and the fastest way to do that is to look at the time to first byte (TTFB) versus the time to render. If your server responds quickly but the page still takes seconds to paint, the problem is almost certainly your code, your assets, or your database queries. If the server itself takes a long time to send back even a tiny response, then your hosting is the bottleneck, and no amount of front-end optimization will fix it. This article walks you through a concrete diagnostic method for the search phrase is my hosting slow or my website, using tools you already have in a terminal.

Start With a Raw Request, Not a Browser

Your browser hides the network timeline behind rendering, JavaScript execution, and a hundred parallel requests. To isolate the host, you need a single, minimal request that bypasses all of that. Use curl with flags that show you the timing breakdown. The command below sends a simple GET request to your homepage and prints every timing stage, including DNS lookup, TCP connection, TLS handshake, and the critical time_starttransfer, which is the moment the first byte of the response arrives.

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://yourdomain.com

Run that three times in a row, because a single run can be skewed by a cold cache or a transient network blip. Look at the TTFB value. If it is consistently above a few hundred milliseconds for a static page, your hosting is the problem. If it is under that but the total time is high, the delay is happening after the server sends its first byte, which points to your site. For a more precise test, request a tiny static file, like a favicon or a single CSS file, instead of the homepage. That removes PHP execution and database queries from the equation entirely. If the static file has a low TTFB but the homepage does not, your hosting is fine and your application code is slow.

Check the Server Response Headers for Clues

Headers tell you which layer of the stack is adding latency. Run curl -I to see only the response headers, and pay attention to Server, X-Powered-By, and any caching headers like X-Cache or Age. A response that includes Age or X-Cache: HIT means a reverse proxy or CDN served the request, so the origin server never even saw it. If you see those headers and the TTFB is still high, the proxy itself is slow, which is a hosting infrastructure issue. If you see X-Powered-By: PHP/8.x and no caching headers, then every request is hitting your PHP interpreter, and the time is going into script execution.

curl -I https://yourdomain.com

HTTP/2 200
server: nginx
date: Tue, 01 Jan 2030 00:00:00 GMT
content-type: text/html; charset=UTF-8
x-powered-by: PHP/8.2
cache-control: no-store

The absence of any caching header on a static page is itself a finding. It tells you that your hosting is not configured to cache responses, so every visitor triggers a full application run. That is not necessarily a hosting failure, but it is a configuration gap that makes your code the bottleneck. If you control the server, you can fix this by adding a caching layer, such as FastCGI cache in nginx or a page cache plugin, and then re-run the same curl command. If the TTFB drops dramatically after enabling caching, the hosting was never slow; your uncached code was.

Profile the Database, Because That Is Usually the Real Culprit

When TTFB is high but static files are fast, the next place to look is the database. Your hosting may be perfectly responsive, but a single query that scans a large table without an index can add a second or more to every page load. Enable the slow query log in your database server, or run EXPLAIN on the queries your application generates. The command below shows you how to check for missing indexes on a typical query pattern.

EXPLAIN SELECT * FROM posts WHERE author_id = 42 ORDER BY created_at DESC;

+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                       |
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------+
|  1 | SIMPLE      | posts | ALL  | NULL          | NULL | NULL    | NULL | 5000 | Using where; Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------+

The type column says ALL, which means a full table scan, and rows says 5000, which means the database is reading every row. That is your bottleneck. Add an index on author_id and created_at, then re-run the query. If the type changes to ref or range and rows drops to a handful, you have found the problem. This is not a hosting issue at all. Your hosting provider could give you a dedicated server with NVMe storage and it would not help, because the database is doing the same full scan either way.

Measure the Asset Pipeline Separately

Sometimes the server is fast, the database is fast, but the page still feels slow because of unoptimized JavaScript, CSS, or images. To isolate this, open your browser developer tools, go to the Network tab, and look at the waterfall. Filter by JS and CSS. If you see a single JavaScript file that takes several seconds to download, that is a hosting bandwidth or asset size problem. If the file downloads quickly but the page still waits, the browser is spending time parsing and executing it, which is your code problem. A quick terminal check for asset size is curl -sI on the file URL and look at the Content-Length header. A multi-megabyte JavaScript bundle is not a hosting failure, it is a build configuration failure. Split the bundle, defer non-critical scripts, and compress images. Re-run the curl timing test on the homepage after those changes, and you should see the total time drop even though the TTFB stays the same.

Use a Second Location to Rule Out Your Own Network

Your local internet connection can make a fast host look slow. Run the same curl timing command from a different network, such as a cloud shell, a friend's machine, or a free online HTTP timing tool. If the TTFB is low from the remote location but high from your office, the problem is your ISP, your router, or your DNS resolver. In that case, neither your hosting nor your code is at fault. You can also switch your local DNS to a public resolver and re-run the test. DNS resolution time is visible in the time_namelookup field from the first command. If that number is high, your DNS provider is slow, not your host.

Is My Hosting Slow or My Website, the Decision Tree

By now you have four data points: TTFB for a static file, TTFB for a dynamic page, database query plan, and asset sizes. If the static file TTFB is high, your hosting is slow. If the static file is fast but the dynamic page is slow, your application code or database is the problem. If both are fast but the page still feels slow in a browser, your front-end assets are the problem. If everything is fast from a remote location but slow from your desk, your network is the problem. That is the entire diagnostic method. It takes about ten minutes and requires no paid tools.

What to Do Next

Once you have identified the layer that is slow, act on that layer only. If the static file TTFB is high, contact your hosting provider with the curl output and ask them to explain the latency, or plan to migrate to a provider with lower network latency. If the dynamic page is slow, profile your application with a profiler like Xdebug or a framework-specific tool, and fix the slow queries and loops. If the assets are heavy, run a build tool to minify and split them. Do not buy a more expensive hosting plan until you have proven that the hosting is the slow layer, because the same code will run just as slowly on a faster server. Re-run the same curl command after each change, and only move to the next layer when the current one is clearly fast.

Related articles

Subscribe to our newsletter

Get the latest hosting tips, performance insights, and industry news.