A service map is one of the most valuable views in modern observability — when it works. The catch is that the value comes from the underlying OpenTelemetry traces, not the visualisation. If your spans have broken parent-child relationships, drifting service names, or inconsistent host identity, the map will look impressive and tell you nothing useful. This post walks through the trace hygiene that makes the difference between a service map that shortens incident time and a service map that becomes decorative wallpaper.
Preserve parent-child span relationships
A service map is built by walking the parent-child links between spans across services. When a request crosses a process boundary, the calling service must propagate the trace context (W3C traceparent header by default) so that the receiving service can attach its spans as children of the caller's span. When propagation breaks, the receiving service's spans become root spans — and the map shows two disconnected services instead of one dependency edge.
The most common places propagation breaks: HTTP clients that don't use an instrumented client library, message queues without explicit header propagation, background workers that pick up jobs without injecting the parent context, and database clients that wrap raw protocols. Audit each of these in your stack. OpenTelemetry's official propagation documentation describes the spec; our signals doc explains how propagation interacts with logs and metrics.
Use stable service names
The map identifies a node by service.name. If your resource attributes include the deployment hash, the pod ID, or a randomised suffix, every deploy creates a new node and old nodes go quiet. Within a week you have a map full of dozens of "checkout-7f3a9"-style nodes and no useful edges. Keep service.name stable across deploys. Use service.version or deployment.environment to separate variants — Telemtra and other OpenTelemetry-aware backends honor these as filters without polluting the map.
For a deeper rationale on naming hygiene, see OpenTelemetry best practices for production.
Keep host identity consistent
Host attributes (host.name, k8s.pod.name, k8s.node.name) let you connect service-level latency to host-level saturation. If your traces use one host name format and your host metrics use another, you lose the ability to correlate a service's p99 latency spike to a noisy neighbour or a saturated node. Align host identity using the OpenTelemetry Collector's resourcedetection processor so every signal coming off a node carries the same identifier.
Use the map as a drilldown, not a wallpaper
The valuable part of a service map isn't the picture — it's that an edge with elevated p95 latency or errors should be one click away from sample traces, the logs that came out of those traces, and the metric that triggered an alert. If your map view is read-only and disconnected from logs/metrics, you've built decoration. The whole point is that "service B is slow when called from A" should resolve to "and here are the three traces that prove it" without leaving the screen.
Telemtra's Service Map view is built around this drilldown. Every edge shows live request count, error rate, and p95 latency, and clicking through to traces or logs preserves the service/operation context.
Related reading
- OpenTelemetry best practices for production — naming, sampling, cardinality.
- OpenTelemetry sampling: head, tail, what to keep — sampling can break a map if you drop the wrong spans.
- OpenTelemetry signals doc — how logs, traces, and metrics share context.