Traces
Service Maps and Dependency Graphs
How aggregating trace data into a visual dependency graph reveals a system's real architecture, and where that picture falls short.
Last updated
A service map is a graph where nodes are services and edges are the calls between them, built automatically by aggregating the parent-child relationships found across many traces. Rather than someone manually drawing an architecture diagram and hoping it stays current, a service map is derived directly from what actually called what, over some recent window of real traffic.
Because it’s generated from observed spans rather than documentation, it tends to reflect the system as it actually behaves — including the dependencies nobody wrote down and the ones that were supposed to have been removed two refactors ago.
Why it matters
- It shows the architecture as it actually is, not as it was designed. Systems drift: services get new dependencies, old ones get half-deprecated, and teams lose track of who calls whom. A service map generated from live trace data surfaces this drift automatically, often revealing calls nobody expected to still exist.
- It’s a fast tool for blast-radius analysis during incidents. When a service is degraded, the dependency graph immediately shows which upstream services are calling it and which downstream services it depends on, letting responders reason about impact and root cause without reconstructing the topology from memory.
- It highlights unexpected or risky coupling. A service map can expose things like a low-tier internal tool calling directly into a critical payment service, or a supposedly independent service secretly sharing a dependency with another team’s — the kind of coupling that’s easy to miss until it shows up visually as an edge that shouldn’t be there.
- It gives new team members a real, current picture of the system. Onboarding engineers into a microservice architecture from documentation alone is unreliable; a live service map grounded in actual traffic is a far more trustworthy starting point.
How it works
- Nodes and edges are derived from span relationships. Tracing backends inspect the parent-child structure of spans — typically identifying client and server spans for the same logical call using semantic conventions — and aggregate those relationships across many traces into a graph, usually also attaching metrics like request rate, error rate, and latency to each edge.
- Some backends compute this as a dedicated metrics pipeline rather than a query-time view. Grafana Tempo, for example, generates service graph metrics from streaming trace data and writes them to a Prometheus-compatible store, so the map is backed by pre-aggregated time series rather than being recomputed from raw traces on every page load.
- Failed or unreachable downstream calls can show up as “virtual” nodes. If a service is completely unreachable and never emits a span of its own, some of these systems synthesize a placeholder node from the caller’s side of the call so the failure is still visible on the map, even though the failing service contributed no telemetry of its own.
- Cardinality and volume are real operational constraints. Every additional dimension attached to an edge (extra labels, custom attributes) multiplies the number of distinct time series the underlying store has to track, so most implementations bound the number of tracked edges and prune old ones to control memory use.
Limitations
A service map is only as complete as the traces feeding it — it can only show a dependency if that dependency was actually traced and actually sampled into the dataset the map is built from. A dependency that only appears in requests hit by aggressive sampling may simply never make it onto the graph, giving a false sense of a cleaner architecture than actually exists. Likewise, services or infrastructure that don’t participate in distributed tracing at all — a legacy component, an external third-party API, some batch jobs — are invisible on the map regardless of how central they are to the system, which means a service map should be read as “what we’ve observed,” not “the complete architecture.”
Related tools
A CNCF-graduated, open-source distributed tracing system originally built at Uber, now rebuilt on the OpenTelemetry Collector core.
Grafana Labs' open-source tracing backend that stores traces in object storage and indexes only trace IDs, trading flexibility for low cost at scale.
An AI-assisted, full-stack observability platform built around automatic instrumentation and causal root-cause analysis.
A unified commercial observability platform covering infrastructure metrics, APM/distributed tracing, log management, and continuous profiling.