"The site is slow" is really three questions: is your app slow to build the response, is the proxy or SSL layer slow, or is the network between the visitor and the server slow? Guessing wastes hours. One command tells you which one it is.
| At a glance | |
|---|---|
| You need | Your app's public address from the Network page, and any second computer |
| First move | Time the request from a machine that isn't the server |
| Plan | Any — but free shares CPU and RAM, which is part of this story |
Measure it, don't guess
Run this from your own computer, not the server (timing a request to yourself is meaningless — it never leaves the box). curl can print exactly where the time goes:
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" http://YOUR-ADDRESS:PORT/
Each number is the cumulative time to reach that stage, so read them as a waterfall — the big jump between two lines is where the time is spent.
💡 Tip: Run it three or four times. A slow first request that's fast afterwards is usually a cold cache or a just-woken free server, not a real latency problem.
Read the split
| The jump is between… | It means | Look at |
|---|---|---|
| start → dns | Name resolution is slow | Your subdomain / domain's DNS (Network page) — or skip it and hit the raw address:port |
| dns → connect | The network path to the node is slow | Distance/route to the node, or a Firewall rate-limit rule |
| connect → tls | The SSL handshake is slow | Your Reverse Proxy domain (only applies over https://) |
| tls → ttfb | Your app is slow to produce the first byte | Your code — this is server-side work |
| ttfb → total | The response body is large or bandwidth-bound | Response size, images, payload |
ttfb (time to first byte) is the one that matters most. If everything up to connect is quick and ttfb is the big number, the network is fine and your app is the bottleneck — no amount of proxy tweaking will help.
App slow: the server-side levers
When ttfb is high, the work is in your code or its resources:
- You're out of headroom. On the free plan you share 2.5 GB of RAM and CPU with other servers on the node; a heavy request, a busy loop, or a memory leak makes everything crawl before it ever crashes. Check the Console page's live CPU and RAM cards while you send a request — if RAM is pinned at the limit, that's your answer. See Out of memory.
- Every request does slow work. A database query with no index, an external API call, or re-reading a big file on every hit adds straight to
ttfb. Do the expensive thing once and reuse it — an in-memory value or Redis cache turns a slow endpoint fast. - You're getting hammered. If traffic (or a bot) is flooding an endpoint, legitimate requests queue behind it. Rate limiting your API protects the rest of the app.
🎯 Good to know: Free servers share hardware, so "slow under load" is partly the plan. Premium gives you your plan's dedicated RAM/CPU and 24/7 uptime — if you've tuned the app and still need more consistent speed, that's the lever.
Proxy or network slow
If ttfb is quick but the earlier stages are slow:
- A fresh reverse-proxy domain can be slow or refuse
https://until its certificate finishes — check the SSL status shows active, not pending, on the Network page's Reverse Proxy tab. See Domains and HTTPS. - The plain
http://address:portpath has no proxy and no SSL in the way — if that's fast but your domain is slow, the proxy layer is the difference. - The Firewall can throttle: a Rate limiting rule you added drops or delays requests once a source crosses the threshold. Its analytics show a blocked/limited count. See The Network page.
Verify the fix
Change one thing, then re-run the same curl and watch the number you targeted drop. That tight loop — measure, change one thing, measure again — is the whole game; it stops you from "optimizing" a part that was never slow.
The -w write-out variables above are standard curl; the full list lives in curl's own docs at curl.se if you want to time more stages.