devops

What I'd Check First on a Slow Site

cachingdevopsmonitoringperformancetroubleshooting
Gerald VillorenteOctober 31, 20269 min read
What I'd Check First on a Slow Site

"The site is slow" is the vaguest ticket in tech support and the most commonly mishandled page in on-call. Nobody can act on it directly, because slowness is a symptom with a dozen possible diseases. This guide gives you a fast, repeatable way to diagnose a slow website: confirm the scope, isolate which layer is slow, run down the five usual suspects in order, and know exactly when slowness graduates into an incident.

The principle is the same one that runs the whole response series: narrow before you fix. Every minute spent guessing at random configs is a minute the site stays slow. Fifteen disciplined minutes of isolation beats an hour of hunches, and the checklist below fits in fifteen minutes once you have run it twice.

Here is the sequence:

  1. Confirm it is slow for everyone

  2. Isolate the layer: frontend, backend, or database

  3. Check the five usual suspects in order

  4. Reach for profiling tools

  5. Capture evidence before you touch anything

  6. Fix, verify, and watch

  7. Know when slow becomes an incident

  8. Build the dashboard that prevents repeats

Confirm It Is Slow for Everyone

Half of all slowness reports evaporate at this step, so never skip it. Slow for one person on hotel wifi is a network story, not a site story. Ask the reporter for the basics: which page, since when, which browser and network, and whether colleagues see it too. Thirty seconds of scoping here saves thirty minutes of chasing ghosts.

Then measure it yourself from somewhere neutral. This one command prints the total time your server took to answer:

curl -s -o /dev/null -w "total: %{time_total}s\n" https://your-site.example/slow-page

It fetches the page silently and reports only the elapsed time. Run it a few times and from more than one location if you can. Consistently slow from everywhere means the problem is yours. Fast from the server's own network but slow from outside points at DNS, CDN, or transit. Intermittent slowness that comes and goes on a rhythm smells like a cron job or a cache expiring, which we will meet again in section 3.

Write down the numbers with timestamps. "Homepage 8.4 seconds at 14:02, 8.1 at 14:05" is the baseline your whole investigation compares against. Without it, you will argue about whether anything improved.

Isolate the Layer: Frontend, Backend, or Database

A page load has three neighborhoods, and the fix lives in only one of them. Splitting them early prevents the classic waste: the frontend developer optimizing images while the database burns.

Start with the browser's developer tools on the slow page. The network tab breaks the load into pieces: time to first byte, content download, and rendering. Slow time to first byte means the server is the problem, so stay on this guide. Fast server response with a slow full load means heavy assets, render-blocking scripts, or third-party widgets, which is a frontend project, not an incident.

If the server is slow, split it once more: application or database? Check the database directly with your slowest known query or the database's own timing. If simple queries fly but the page crawls, the application layer is the suspect: saturated workers, a blocking call to an external service, a loop that grew with the data. If the database itself is slow on simple queries, stay there. Each split halves the search space, and two splits turn "the site is slow" into a named neighborhood.

The Five Usual Suspects, in Order

Across years of slow sites, the same five causes cover the large majority of cases. Check them in this order, most common and cheapest to verify first.

  1. Cold or broken cache. The number one cause, by far. A deploy that cleared caches, a cache server that restarted, or a cache key change means every request suddenly hits the database at full force. Check cache hit rates first. A rate that fell off a cliff at the exact moment slowness started is a confession.

  2. The database working too hard. Missing indexes on a grown table, or an N+1 query pattern that fires hundreds of small queries per page. Look at the slow query log for newcomers and repeat offenders. A query that scanned a thousand rows last year scans millions now, and nobody changed anything except time.

  3. Saturated application workers. If every worker is busy, new requests queue, and queueing looks exactly like slowness. Check worker utilization and queue depth. A traffic bump, a stuck job holding workers, or a downstream call timing out and piling up can all saturate a pool that was fine yesterday.

  4. A runaway scheduled job. The cron that imports, aggregates, or backs up at the wrong hour, locking tables or eating I/O. Slowness on a daily rhythm, same time every day, is almost always scheduled. Match the slow window against the job schedule before touching anything else.

  5. A slow external dependency. Payment gateways, maps, analytics, single sign-on. One sluggish third party with no timeout becomes your slowness, because your page waits for their answer. Check dependency response times, and confirm your timeouts are sane so their bad day is not automatically yours.

Work the list top to bottom and stop at the first confession. Resist the urge to tune the database when the cache graph already told you the answer.

Reach for Profiling Tools

Guessing is slow. Once you know which layer hurts, let a profiler show exactly where time goes before you change anything.

  • New Relic APM. Use it to find slow transactions, slow endpoints, and time split between application code, database calls, and external services. Start with the transactions view sorted by slowest average response, then open a transaction trace to see which span actually burns the time.

  • Percona Toolkit for MySQL-based databases. If your database is MySQL or MariaDB, run pt-query-digest against the slow query log. It ranks query patterns by total time, so you fix the one pattern that costs the most instead of the one you happened to notice first.

  • Analyze the logs. Read the slow query log for repeat offenders, plus web server access logs for slow URLs and application logs for downstream timeouts. Correlate timestamps with your slow window from section 1, so you only chase entries inside the incident.

  • Add caching layers: Redis and CDN. When profiles show repeated identical reads, put Redis in front of the database for hot keys and session or fragment caches. When profiles show heavy static traffic or repeat full-page loads, put a CDN in front for edge caching and compression. Reprofile after warming the cache to confirm the hot path actually shortened.

Pick one tool per slow episode, the one that matches the layer you isolated. A profiler result beats a hunch every time, and it gives your evidence snapshot in the next section real numbers to hold onto.

Capture Evidence Before You Touch Anything

Diagnosis that is not written down is a story you will retell wrong. Before changing a single setting, snapshot the scene: current response times, the graphs showing when it started, the top slow queries, worker and queue counts, and anything you ruled out with timestamps. Screenshots of dashboards count. Memory does not.

This snapshot serves three masters. First, it proves the fix worked, because you can compare after against before instead of relying on feel. Second, it feeds the postmortem if slowness becomes an incident, with the timeline half-written. Third, it protects you when the fix has side effects: "query time was already degrading before my change" ends arguments that evidence-free debugging cannot.

Save it where the team can find it: the incident channel, the ticket, the shared drive. Evidence in a personal notebook helps nobody at 3am except its author.

Fix, Verify, and Watch

Apply the smallest fix that addresses the found cause. Warm the cache instead of redesigning caching. Add the missing index instead of rewriting the query layer. Kill or reschedule the runaway job instead of re-architecting background work. Small fixes are verifiable, reversible, and shippable during an ongoing slowdown. Save the redesign for the calm week after, filed as a real ticket with an owner.

Then verify against your baseline, not your hopes. Re-run the same measurements from section 1: same pages, same method. The numbers should move clearly, not arguably. If they barely moved, you found a contributor, not the cause. Keep going down the list instead of declaring victory over noise.

Watch for at least as long as the slow period lasted. Caches need time to warm, queues need time to drain, and some fixes look perfect for ten minutes before regressing. Set a reminder to check back in an hour. Premature celebration is how the same slowness pages you twice in one night.

Know When Slow Becomes an Incident

Not every slow site is an incident, but slowness crosses the line more often than teams admit. Declare it when any of these hold: checkout, signup, or payment flows are affected; the degradation is getting worse by the hour; or customer reports are arriving faster than you can answer them. At that point, stop solo debugging and run the outage playbook: declare, assign roles, stabilize, communicate, then diagnose with the team behind you.

The threshold deserves writing down before you need it. Agree with your team now on what "slow enough to declare" means in numbers: page loads over N seconds, error budgets burning faster than X, support queue growing past Y. Pre-agreed thresholds remove the hardest part of the decision, which is making it under pressure while someone argues it is not that bad.

Build the Dashboard That Prevents Repeats

Every slow episode you diagnose by hand is a dashboard you have not built yet. The permanent fix for performance firefighting is visibility that catches degradation before humans feel it: response time percentiles (not averages, which hide the suffering tail), cache hit rates, slow query counts, worker saturation, queue depth, and dependency latencies, all on one page the team actually opens.

Alert on the trends that matter, following the alerting discipline of paging only on user pain: response time percentiles crossing agreed thresholds, cache hit rate cliffs, queue depth growth. And review the numbers the way the support metrics guide teaches: trends over snapshots, paired metrics over single ones.

Do this and slow stops being a recurring emergency. It becomes a graph that drifts, an alert that fires early, a checklist that resolves it, and a runbook entry that makes the next one boring. That is the whole arc of this series: detect calmly, respond calmly, learn permanently. The site gets faster, the nights get quieter, and the next "the site is slow" ticket arrives with the answer half-written.

Related reading

Alerts That Earn the 2am Wake-Up
devops

Alerts That Earn the 2am Wake-Up

October 31, 2026
alertingdevopsmonitoringon-call
Read →
The First Five Minutes of an Outage: What to Do Before You Know What's Wrong
devops

The First Five Minutes of an Outage: What to Do Before You Know What's Wrong

October 31, 2026
devopsincident-responseon-callproduction
Read →