Monitoring has a way of turning into a wall of graphs nobody reads. The four golden signals are the antidote: a short, opinionated list of what's actually worth watching for any service users hit directly. They come from Google's SRE practice, and the reason they've stuck is that they're complete enough to catch most real problems and short enough that a team will actually keep them up.
Where they come from
Google's Site Reliability Engineering book (2016, freely available online) introduced the four golden signals as the minimum set of service-level signals worth monitoring. They're the prioritization answer to "if you can only monitor four things, monitor these."
Signal 1 — Latency
How long requests take. Measured in percentiles, not averages. Track p50, p95, p99 per route. Alert on sustained p95 elevation against a rolling baseline.
Laravel: the Nightwatch package records per-request duration. NightOwl groups by route pattern and computes percentiles automatically.
Signal 2 — Traffic
How much demand your service is receiving. Usually requests per second or per minute. Useful two ways: spot unusual load (attack, viral moment, Monday morning traffic) and sanity-check other signals (a latency spike during 10x traffic is different from one at normal load).
Laravel: requests per minute per route. Include 2xx, 3xx, and 4xx — every request counts as traffic.
Signal 3 — Errors
Rate of failed requests. Usually expressed as a percentage of total traffic. Also includes errors that return 200 but failed business logic (a checkout that returned 200 with an "inventory unavailable" message).
Laravel: 5xx response rate per route, unhandled exceptions per minute, grouped by fingerprint. Pair with report() for expected-exception tracking.
Signal 4 — Saturation
How full any bounded resource is. The leading indicator — saturation climbs before latency spikes or errors jump. Most important and hardest to measure.
Laravel-specific saturation surfaces:
- PHP-FPM pool — what % of
pm.max_childrenare busy. Query viapm.status_path. - Queue depth — pending jobs per queue. Rising depth = consumer lag.
- Queue latency — dispatch-to-start time. See our queue latency guide.
- DB connection pool —
max_connectionsusage in Postgres'spg_stat_activity. - Redis memory —
used_memoryas a % ofmaxmemory. - Disk — log volumes, session storage, uploaded file storage.
Putting them together
| Signal | Laravel metric | Alert style |
|---|---|---|
| Latency | p95 per route | Sustained threshold breach |
| Traffic | req/min per route | Anomaly detection both ways |
| Errors | 5xx rate, new exceptions | Immediate on new groups |
| Saturation | Pool %, queue depth, DB conns | Headroom threshold (e.g. 90%) |
How they fail together
The signals are most useful read as a set, because a real incident moves several at once and the pattern tells you what kind of incident it is.
A deploy ships a slow query: saturation climbs first as workers stay busy longer and the queue backs up, then latency follows as p95 rises, and if it gets bad enough errors appear when requests start timing out. Traffic stays flat the whole time — that flatness is the tell. Demand didn't change, something you shipped did.
Compare a traffic spike: traffic jumps first, saturation follows as workers fill up, and latency and errors only move if you ran out of headroom. Same downstream symptoms, opposite root cause, and you can tell them apart in seconds — but only because you were watching traffic too. Latency alone would have left you guessing.