# Diagnose a slow or erroring site

**Goal:** go from a symptom ("the site is slow", "users are seeing errors", "the nightly job didn't run") to the log or metric that explains it.

## What you'll have when you're done

- The symptom narrowed to a layer (edge cache, PHP, database, infrastructure) with evidence from the right log or metric.
- A concrete next action: a query to fix, code to profile, a purge, a rollback, or a support ticket.

## Prerequisites

- [What the platform logs](/cloud-platform/observability/logs/): the log catalog, and how to open one
- [acli installed and authenticated](/cloud-platform/cli/quickstart/), or access to the Cloud Platform user interface

## Steps

Jump to the symptom you have: slow site (step 1), visible errors (step 2), a job that didn't run (step 3), or suspected resource pressure (step 4).

<Steps>

1. ### The site is slow

   Work from the outside in:

   **Is it even reaching PHP?** A well-cached site serves most anonymous traffic from [Varnish](/start-here/glossary/#varnish). If pages that should be cached show `X-Cache: MISS`, you have a cacheability problem, not a performance problem; fix that first (see [fix stale content](/cloud-platform/caching/stale-content/), the same header-reading applies).

   **Is PHP slow, or starved?** Open the Drupal request log and look at two fields per request:

   ```
   [03/Feb/2026:00:14:36 +0000] www.example.com GET /pricing
   http_code=200 query= uid=0 php_pid=30961 php_time=4.203 queue_wait=0 ...
   ```

   - High `php_time`, low `queue_wait`: the request itself is expensive. Something in code, queries, or external calls is slow; continue below.
   - Low `php_time`, high `queue_wait`: requests are healthy but waiting for a free PHP process. The site is under-provisioned or being hammered; check traffic in the Apache access log and resource use in Stack Metrics (step 4).

   **If requests are expensive, suspect the database next.** Download the MySQL slow-query log ([`acli api:environments:log-download`](/cloud-platform/observability/logs/#download-it-for-problems-that-already-happened); it's generated on demand and covers since the last daily rotation). Entries are standard MySQL slow-log format:

   ```
   # Time: 2026-07-03T02:11:07
   # User@Host: mysite[mysite] @ localhost []
   # Query_time: 4.882  Lock_time: 0.001  Rows_sent: 12  Rows_examined: 2847391
   SELECT ... FROM node_field_data n INNER JOIN ...
   ```

   The ratio that matters is `Rows_examined` to `Rows_sent`: this query scanned 2.8 million rows to return 12, which means a missing index or a query (often a Drupal View) that needs restructuring. For logs with many entries, [pt-query-digest](https://docs.percona.com/percona-toolkit/pt-query-digest.html) aggregates them by fingerprint; for a single suspect, `EXPLAIN` it over [drush sql-cli](/cloud-platform/cli/everyday-workflows/#run-drush-remotely-or-open-a-shell).

   **If the database is fine, profile the application.** That's what an APM is for: Acquia subscriptions include New Relic APM Pro (claim it per [Claiming your New Relic account](https://docs.acquia.com/acquia-cloud-platform/claiming-your-new-relic-apm-pro-account) on docs.acquia.com), which breaks request time down by function, query, and external call. Common culprits the platform's own guidance names: complex Views queries, calls to slow external services without timeouts, and oversized result sets processed in PHP.

2. ### Users are seeing errors

   - **HTTP 500s**: open the PHP error log first; application errors land there with a stack trace. If it's empty for the time window, check the Apache error log for infrastructure-level failures. A request that outlives PHP's `max_execution_time` (300 seconds by default, tunable per environment; see [per-environment settings](/cloud-platform/configure/settings/#tune-php-settings-where-the-platform-allows)) is killed and returns a 500; the fix is moving the work to a [scheduled job](/cloud-platform/configure/cron/), not raising the limit.
   - **Errors you can't reproduce**: find one failing request in the Apache access log, grab its `request_id`, and follow that ID across the Drupal request and error logs to see exactly what that request did.
   - **White screens / partial pages**: PHP error log again (fatal errors), then Drupal watchdog (`drupal-watchdog.log`, needs the `syslog` module) for application-level reports.
   - **It's happening right now**: stream instead of downloading, `acli app:log:tail myapp.prod`, or the interface's `Logs` page with the error logs selected. See [tail logs](/cloud-platform/cli/everyday-workflows/#tail-logs-from-an-environment).

3. ### A background job didn't run

   1. Check the job's own output: scheduled-job STDOUT is captured in `cronjob.log` (download from `Logs`). No entry at the expected time means the job didn't fire (check its schedule and environment, see [scheduled jobs](/cloud-platform/configure/cron/)); an entry with errors means it fired and failed.
   2. If the job is Drupal cron, also check watchdog: cron logs its runs there.
   3. Jobs that run over SSH but silently do nothing often point at the wrong environment or docroot; re-run the command manually over [SSH](/cloud-platform/cli/everyday-workflows/#run-drush-remotely-or-open-a-shell) and read the output directly.

4. ### Check resource pressure with Stack Metrics

   `acli api:environments:stack-metrics-data-find` returns an environment's stack metrics as data, taking a metrics filter and a start time. The Cloud UI graphs the same CPU, memory, and storage over time (last hour to last 6 months); see [Using Stack Metrics](https://docs.acquia.com/acquia-cloud-platform/using-stack-metrics-monitor-activity-your-environments) on docs.acquia.com. Two reading rules from the platform's own docs:

   - Graphs show averages over the window, so short spikes are smoothed away; sustained elevation is what matters.
   - On [Cloud Next](/start-here/glossary/#cloud-next), resources scale dynamically and load-balancer metrics reflect shared infrastructure, so low CPU on an idle site is normal. If auto-scaling isn't keeping up, [open a support ticket](https://acquia.my.site.com/s/contactsupport).

   Use Stack Metrics to answer "is the box the problem", and the logs above to answer "what is my application doing to it". For continuous, code-level visibility, New Relic (step 1) is the deeper tool.

</Steps>

## When something goes wrong

**The errors started with a deploy**: stop diagnosing and roll back first: [Roll back a release](/cloud-platform/code-workflow/guide/#roll-back-a-release) in the code-workflow guide is the runbook.

**The logs don't explain it**: infrastructure-side problems (shared load balancers, platform maintenance) aren't visible in your logs; that's when to [open a support ticket](https://acquia.my.site.com/s/contactsupport) with the `request_id` of an affected request.

## Next steps

- [What the platform logs](/cloud-platform/observability/logs/): the full catalog this page draws from.
- [Fix stale content](/cloud-platform/caching/stale-content/): when the symptom is "wrong content", not "slow content".
- [Run scheduled jobs](/cloud-platform/configure/cron/): setting up the background work this page helps you debug.
