Fundamentalsobservabilitymonitoringunknown unknownssignalsdebugging

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.

Follow the diagnosis

Frame the diagnosis

Performance work starts from a symptom and a signal — never from a resource dashboard.

Diagnostic question
Can I answer a question about this system that nobody anticipated when it was instrumented?
Symptom
Something is clearly wrong — customers are complaining — and every dashboard is green. The only way forward anyone can suggest is to add logging and redeploy.
Signal
The honest signal is a question test: pick a question you did not have yesterday ("is this slow only for tenant X on the mobile client?") and see whether existing data answers it. The misleading signal is dashboard count — a wall of charts measures how many questions you *already* asked, not how many you *can* ask.
SymptomSignalMeasurementHypothesisEvidenceRoot CauseChangeValidationRegression Check

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.

The same outage, from two postures
Question at 03:00Monitored systemObservable system
Are we down?Yes — the availability panel is redYes — the SLI shows 4.2% of requests failing
Which endpoint?Unknown; the panel is service-widePOST /checkout only; every other route is nominal
All users, or some?UnknownOnly requests carrying the eu-west region attribute
Started when, and after what?Roughly 14:00, from the chart14: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 watchDisable 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.

What the outside can see
symptomemitsemitsemitsemitsonly pre-declared dimensionsarbitrary attributesfull context, high costin-process cost onlyUser: "checkout is slow"Service (opaque)Metrics: rates, aggregatesLogs: discrete eventsTraces: one request, all hopsProfiles: cost inside the processA question you did not ask yesterday
UserLLMAgentToolDataDecisionHumanGuardrail

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.

ILLUSTRATIVE — relative telemetry cost for one mid-size service. Real ratios depend entirely on traffic, retention and vendor pricing.
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.

  1. 1
    Incident → dashboards: every pre-built panel is green or ambiguous, because the failure mode was not one of the ones anticipated.
  2. 2
    Engineer → metrics: the aggregate confirms something is wrong but cannot be sliced by the dimension that matters (client version, tenant, region).
  3. 3
    Engineer → logs: logs contain the events but no correlation id, so the hop that consumed the time cannot be attributed.
  4. 4
    Engineer → code: the only remaining move is adding instrumentation and deploying, which takes longer than the incident.
  5. 5
    Team → postmortem: "we could not tell which dependency was slow" appears as an action item, again.
What this evidence makes people conclude — wrongly
  • "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.

How to measure it
  • • 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.
What actually fixes it
  • • 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.
How you know it worked
  • • 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.
What it costs
  • • 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]]).
Stop it coming back
  • 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.

What these numbers depend on
  • 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.

Misconceptions

Claim
“Observability is a product you buy.”
Reality
It is a property of your telemetry: enough dimensions, correlated across hops, queryable after the fact. Vendors sell storage and query engines for that data — they cannot supply context your code never emitted.
Claim
“Monitoring and observability are just different words for the same thing.”
Reality
Monitoring watches questions you already chose; observability lets you ask new ones. A system can be heavily monitored and completely opaque during a novel failure.
Claim
“More dashboards mean better observability.”
Reality
Dashboards are frozen answers to yesterday's questions. They are useful, but the number of them is uncorrelated with your ability to diagnose something new.