# Service Graph

> Visualize service dependencies, request flows, error rates, and latency across your infrastructure with Uptrace service graphs built from OpenTelemetry span relationships.

Uptrace builds a live service graph from span relationships — no extra configuration required. Every `client`/`server` and `producer`/`consumer` span pair becomes a directed edge in the graph, giving you a real-time map of how your services interact, where traffic flows, and where failures propagate.

<video autoPlay="true" loop="true" muted="true" playsInline="true">
<source src="/video/product/tracing/trace-service-graph.mp4" type="video/mp4" />
</video>

## Reading the graph

Each **node** represents a service (`service.name`). Each **directed edge** represents calls between two services and carries three live metrics:

- **Request rate** — calls per minute across that edge
- **Error rate** — percentage of calls returning errors
- **p99 latency** — 99th percentile call duration

Edges are color-coded: green for healthy traffic, yellow for elevated error rate, red for high errors or slow latency.

Clicking a **node** opens a panel showing the service's inbound and outbound call metrics. Clicking an **edge** shows per-call latency percentiles and an error breakdown between the two services.

## Filters

The graph supports the same filters as [Traces](/features/traces): time range, environment, service name, and any indexed attribute. Filtering by `deployment_environment = production` isolates your production topology from staging traffic.

## Requirements

Service graphs are built automatically from incoming spans. Missing attributes result in missing nodes or edges.

### General attributes

- `service.name` — logical name of the service. Every span must have this.
- `span_kind` — must form `client`/`server` or `producer`/`consumer` pairs across service boundaries. Required for edges to appear.
- `span_status_code` — enables error rate coloring on edges. Recommended.

### RPC calls

- `rpc.service` — full logical name of the service being called.

### Database calls

- `db.name` — database name. Required if you query multiple databases and want each to appear as a separate node.

### HTTP calls

- `server.socket.domain` — domain name of the immediate peer. Required for HTTP edges.
- `server.socket.address` — server IP or Unix socket address. Required when `server.socket.domain` is absent.

### Messaging calls

- `messaging.destination.name` — message destination name (e.g. `MyQueue`, `MyTopic`).
- `messaging.client_id` — unique identifier for the message client.
- `messaging.kafka.consumer.group` — Kafka consumer group name. Applies to consumers only.

## Troubleshooting

**Graph is empty** — confirm spans have `service.name` and that at least one service makes outbound calls to another. A graph requires at least two services with a `client`/`server` span pair.

**Missing edges** — the calling service must emit a `client` span and the receiving service a `server` span with the same `traceId`. If only one side is instrumented, the edge does not appear.

**Nodes appear but no edge metrics** — check that `span_status_code` is set and that HTTP or RPC attributes are present on client spans.

**Database calls not grouped correctly** — add `db.name` to distinguish multiple database instances of the same type.

## Related

- [Traces](/features/traces) — drill into individual spans flowing across service edges
- [Metric monitors](/features/alerting/metric-monitors) — alert on service graph metrics like error rate or latency
- [Semantic conventions](/opentelemetry/semconv) — full reference for span attributes used in service graphs
