Observability Is Not a Dashboard
Monitoring answers the questions you thought to ask when you built the dashboard. Observability is whether you can answer a question nobody anticipated — without shipping new code first. The test is not how many tools you run; it is what you can ask at 03:00.
Frame the diagnosis
Performance work starts from a symptom and a signal — never from a resource dashboard.
Monitoring answers old questions; observability answers new ones
Monitoring is the set of questions you decided in advance were worth watching: is CPU above 80%, is the error rate above 1%, is the queue deeper than 10,000. It is enormously useful and it is not the same thing as observability. A monitored system tells you *that* one of your pre-chosen thresholds moved. It says nothing about the failure mode you never imagined.
Observability is the property that you can reconstruct internal behavior from the telemetry you already emit. The working definition for an engineer on call: can I ask a new question and get an answer without deploying code? If the answer requires adding a log line and waiting for a release, the system is monitored but not observable — and the failure is happening now, not after the release.
The practical difference is dimensionality. A counter of http_requests_total{status="500"} tells you errors went up. It cannot tell you they are all on one endpoint, from one client version, in one region, hitting one shard — unless those dimensions were captured at emission time. Which dimensions to capture is a design decision with a real cost (see Cardinality: The Label That Took Down Monitoring), and it is the decision that determines what you can ask later.
| Question at 03:00 | Monitored system | Observable system |
|---|---|---|
| Are we down? | Yes — the availability panel is red | Yes — the SLI shows 4.2% of requests failing |
| Which endpoint? | Unknown; the panel is service-wide | POST /checkout only; every other route is nominal |
| All users, or some? | Unknown | Only requests carrying the eu-west region attribute |
| Started when, and after what? | Roughly 14:00, from the chart | 14:03:20, three minutes after the v2.4 deploy marker |
| Is it the database or the payment provider? | Both dashboards look "sort of high" | The trace shows 1.8s inside the payment span; the DB span is 40ms |
| What do we do next? | Restart things and watch | Disable the payment retry loop shipped in v2.4 |
The unknown-unknowns test
The useful mental exercise is to write down a question you have never asked before, then check whether your telemetry answers it. "Is p99 worse for requests that also touched the recommendations service?" "Do the slow requests correlate with a specific database replica?" "Is the regression only on clients running the old SDK?" Each of these needs a *dimension* captured at emission time and a way to slice by it after the fact.
This is why the three-signal split matters (see Metrics, Logs, Traces, Profiles). Metrics answer questions about aggregates cheaply but only along the dimensions you pre-declared. Traces answer questions about one request across services, including questions you invent later, because a span carries arbitrary attributes. Logs answer questions about discrete events with full context. Profiles answer questions about cost *inside* a process. A system with only metrics is a system that can only be asked yesterday's questions.
None of this requires a specific vendor. The properties that make a system observable are: high-dimensional context attached to events, correlation identifiers that survive every hop (see Correlation IDs: Turning Lines Into a Story), and the ability to slice arbitrarily after collection. A team can have all three with open tooling and none of them with an expensive platform.
Observability has a bill, and it is not small
Every dimension you capture costs storage, query time and money, and some of them cost production latency. A team that responds to "we need observability" by capturing everything discovers the second failure mode: a telemetry pipeline that costs more than the service it watches, and a metrics backend that falls over when someone adds a user id to a label (see Cardinality: The Label That Took Down Monitoring).
The discipline is to buy dimensionality where questions actually get asked. Request-scoped attributes on traces are cheap and high-value because tracing is sampled. Metric labels are expensive because every combination is a time series stored forever. Logs sit in between and are usually the line item that surprises finance (see The Log Bill and What It Is Buying).
A reasonable starting posture for a service: the four golden signals as metrics with low-cardinality labels (see The Four Golden Signals), traces on a sampled fraction of requests with rich attributes, structured logs for errors and state transitions, and continuous profiling at a low sample rate. That combination answers most new questions without an unbounded bill — and it is a starting point to revise, not a rule.
signal volume/day retention relative $ answers ────────────────────────────────────────────────────────────────────── metrics ~2M points 13 months 1.0x "how many, how often, how fast" (pre-declared slices) traces (2%) ~900k spans 7 days 1.4x "where did THIS request spend time" logs ~40 GB 14 days 4.8x "what exactly happened at 14:03:20" profiles ~50k samples 30 days 0.3x "which function burned the CPU" The line item that surprises teams is almost always logs; the line item that takes down the metrics backend is almost always a high-cardinality label.
Key points
- Monitoring answers questions chosen in advance; observability is whether a *new* question can be answered without shipping code.
- The practical test is dimensionality: can you slice by endpoint, region, client version, tenant and shard after the fact?
- No single signal is sufficient — metrics, logs, traces and profiles each answer a different class of question.
- Observability is a cost decision as much as a tooling decision; buy dimensionality where questions actually get asked.
- A wall of dashboards measures how many questions you already asked, not how many you can ask.
Progressive depth
Overview
Observability is the ability to understand what a system is doing from the outside, using the signals it already emits — without attaching a debugger or shipping new code.
Practical
In practice it means: the four golden signals as metrics, traces with rich request-scoped attributes, structured logs with a correlation id, and profiles for in-process cost. Each answers a different class of question; you need the combination.
Advanced
The limiting factor is dimensionality versus cost. Metric labels multiply into stored time series, so high-cardinality context belongs on traces and logs. Sampling makes rich traces affordable, but biases what you see — head sampling drops the interesting tail unless you add tail-based rules (see Sampling Without Throwing Away the Evidence).
Internals
Underneath, all of this is instrumentation writing to an in-process buffer, a background exporter batching to a collector, and a backend indexing by time and dimension. Every layer can drop data under load — which is why telemetry pipelines need their own health signals, and why "the dashboard went flat" sometimes means the collector died rather than the traffic stopped.
Follow the diagnosis
The causal chain, hop by hop — and the readings that invite the wrong conclusion.
- 1Incident → dashboards: every pre-built panel is green or ambiguous, because the failure mode was not one of the ones anticipated.
- 2Engineer → metrics: the aggregate confirms something is wrong but cannot be sliced by the dimension that matters (client version, tenant, region).
- 3Engineer → logs: logs contain the events but no correlation id, so the hop that consumed the time cannot be attributed.
- 4Engineer → code: the only remaining move is adding instrumentation and deploying, which takes longer than the incident.
- 5Team → postmortem: "we could not tell which dependency was slow" appears as an action item, again.
- • "We have Grafana, so we have observability." Tooling is not the property; being able to answer a new question from existing data is.
- • "All dashboards are green, so the system is healthy." Green dashboards mean none of your pre-chosen thresholds moved — users may still be failing in a dimension you never charted.
- • "We should log everything." That trades an observability problem for a cost and a noise problem, and usually makes the signal harder to find.
- • "Adding more panels improves observability." Panels are answers to old questions; dimensionality is what answers new ones.
Measure, fix, validate
An optimization is not finished until the metric that motivated it has moved.
- • Run the question test: write down three questions you have never asked, then try to answer them from existing telemetry without deploying anything.
- • Count how many incidents in the last quarter required a "add logging and redeploy" step before diagnosis — that number is your observability gap.
- • Check whether a single request can be followed end to end: does a correlation id appear in the gateway log, the service log and the trace for the same request?
- • List the dimensions available on your primary latency metric. If endpoint, status and region are not among them, most new questions are unanswerable.
- • Attach request-scoped context (endpoint, tenant, region, client version, correlation id) to traces and structured logs at the edges, so slicing is possible after the fact.
- • Propagate one correlation id across every hop, including queues and background jobs (see [[correlation-ids]] and [[context-propagation]]).
- • Keep metric labels low-cardinality and push high-cardinality context into traces and logs instead (see [[cardinality]]).
- • Adopt the golden signals as a per-service baseline so a new service is never launched blind (see [[golden-signals]]).
- • Budget telemetry deliberately — sampling rates and retention per signal — rather than discovering the bill after the fact.
- • Re-run the question test after the change: the same three previously unanswerable questions should now be answerable from a query, not a deploy.
- • In the next incident, measure time-to-first-useful-signal. If diagnosis no longer starts with "add a log line", the change worked.
- • Verify a single request id can be followed from the gateway through every downstream hop in one query.
- • High-dimensional telemetry costs money continuously, and the cost scales with traffic rather than with incidents.
- • Instrumentation adds runtime overhead and code that must be maintained alongside business logic.
- • Rich context increases the chance of capturing something sensitive; trace and log attributes need the same scrutiny as any data flow (see [[logs-and-secrets]]).
- • Add a launch checklist item: no service goes to production without the four golden signals and correlation-id propagation.
- • Alert on telemetry health itself — dropped spans, collector errors, ingestion lag — so a silent pipeline failure does not masquerade as a healthy system.
- • Review instrumentation gaps in every postmortem; "we could not answer X" becomes a tracked action item, not a shrug.
Accuracy
Performance numbers are conditional. These are the conditions.
- ILLUSTRATIVEThe telemetry volume and cost ratios are teaching figures. Real ratios depend on traffic shape, retention policy, sampling rate and vendor pricing model, and vary by an order of magnitude between organizations.
- ENVIRONMENT-SPECIFICWhat counts as "sufficient" observability depends on system complexity: a single-process CRUD service needs far less than a 40-service request path.