A monolith is easy to watch: one app, one process, one place to look. Break it into microservices and you get flexibility and scale — but also a new problem: a single user request might touch a dozen services, and "is it healthy?" no longer has a single answer.
Monitoring a distributed system is a different discipline. Here's how to keep your sanity.
Why microservices are harder to monitor
| Monolith | Microservices |
|---|---|
| One app to watch | Dozens of services to watch |
| A failure is here | A failure could be in any service or the calls between them |
| One log stream | Many logs, scattered |
| Simple "is it up?" | "Which part is degraded, and why?" |
The core challenge: failures hide in the connections between services as much as in the services themselves. A slow dependency three hops away can make a user-facing endpoint look broken.
What to monitor
1. Each service's health
Every service needs its own basic checks — is it up, what's its error rate, what's its latency? A simple health endpoint per service is the foundation.
2. The dependencies between them
This is the part that's easy to miss. Service A calls B calls C — and you need to see those relationships. When A is slow, is it A's fault or is it waiting on C? Monitoring dependencies (and their health) is what answers that.
3. Distributed tracing
This is the microservices superpower. Tracing follows one request across every service it touches, showing where the time went and where it failed. Without tracing, debugging a slow request across ten services is guesswork; with it, you see the exact hop.
Monitor symptoms, not just services
With dozens of services, alerting on every internal metric is a fast track to alert fatigue. The antidote:
Alert on user-facing symptoms, investigate with per-service detail. Page someone when "checkout is failing" (a symptom users feel) — then use service metrics and traces to find which service caused it. Don't page on "service-X CPU is 80%" if no user is affected.
This keeps the pager meaningful while still giving you the depth to diagnose.
The golden signals, per service
A practical, low-noise starting point is the golden signals for each important service:
| Signal | Watch |
|---|---|
| Latency | How long requests take (use percentiles) |
| Traffic | How much demand it's handling |
| Errors | The rate of failed requests |
| Saturation | How "full" its resources are |
Four signals per service scales far better than a hundred bespoke metrics.
Don't forget the front door
For all the internal complexity, your users only experience the edges — the public endpoints. So alongside internal observability, keep simple external uptime and API checks on the user-facing services. They're the ground truth for "are customers actually okay?", confirmed from multiple locations.
The bottom line
| In one line | |
|---|---|
| The challenge | Failures hide in services and the calls between them. |
| Watch | Per-service health, dependencies, and distributed traces. |
| Alert on | User-facing symptoms — not every internal metric. |
| Anchor | External checks on the public endpoints = ground truth. |
Microservices don't need more monitoring so much as smarter monitoring: golden signals per service, tracing to follow requests across them, and symptom-based alerting so the noise stays manageable. Watch the edges your users touch, and keep the depth to dig in when something slips.
Related: Observability vs Monitoring, API monitoring, alert fatigue.