> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aiaxoniq.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Services and the service map

> The service inventory and dependency graph aiAxonIQ discovers from your telemetry — what it can show, and the four reasons an edge is missing.

The **service inventory** is every service that has emitted telemetry. The
**service map** is the graph of which of them call which, built from observed
parent-child relationships between spans.

Both are **discovered, never configured**. There is nothing to register and no
topology file to maintain — which also means the map shows what is true rather
than what someone documented.

<Info>
  **Before you start.** You need traces from at least two services that call
  each other. A single service produces an inventory entry and no edges.
</Info>

## What identifies a service

`service.name`, and nothing else.

<Warning>
  **A service that does not set `service.name` becomes `unknown_service`**, and
  every such service collapses into one entry that looks enormous and is not
  anything.

  If your map has a single huge node with edges to everything, this is why. Fix
  it at the source — see
  [Resource attributes](/send-data/otel/resource-attributes).
</Warning>

Two corollaries worth knowing before you name anything:

* **The same name in two environments is one service.** Use
  `deployment.environment` to separate them, not `checkout-api-staging`.
* **The same name in two clusters is one service.** Set a cluster name when
  installing a Collector or agent per cluster, or two clusters silently merge.

## Reading the map

| What you see   | What it means                                                 |
| :------------- | :------------------------------------------------------------ |
| A node         | A service that has emitted telemetry inside the time range    |
| An edge        | Observed calls from one service to another                    |
| A missing node | No telemetry in this window — not necessarily nothing running |
| A missing edge | See below; usually instrumentation rather than absence        |

<Note>
  **The map is scoped to the time range.** A service that was quiet in the last
  15 minutes is absent from a 15-minute map. Widen the range before concluding
  something is gone.
</Note>

## Why an edge is missing

In likelihood order:

<Steps>
  <Step title="Context propagation broke">
    The callee received no `traceparent` and started its own trace, so there is
    no parent-child relationship to draw. The tell is that the callee still
    appears as a node, with its own root traces.
  </Step>

  <Step title="One side is not instrumented">
    A service that emits nothing cannot appear, and its callers show a call to
    an unnamed peer instead of an edge.
  </Step>

  <Step title="Independent sampling">
    Services sampling separately produce partial traces, so some edges exist in
    some traces and not others. See
    [Sampling](/send-data/otel/sampling#the-rule-that-matters-most).
  </Step>

  <Step title="The call is not over an instrumented protocol">
    Work handed over through a queue, a shared database or a file is a real
    dependency that produces no span linking the two.
  </Step>
</Steps>

<Warning>
  **The map shows the edges that carry instrumented traffic — not your
  architecture.** A dependency through a message queue, a shared table or a
  cron job is genuinely invisible here. Do not read an absent edge as an absent
  dependency.
</Warning>

## Zero-code fills the gaps

The most common reason a map is incomplete is that some services were never
instrumented and never will be. The eBPF agent observes them at the socket
boundary, so they appear without anyone changing their code.

That is the strongest case for zero-code instrumentation: coverage of exactly
the services an SDK rollout was never going to reach. See
[Zero-code instrumentation](/zero-code/overview).

## What else is discovered

|                        | From                                                                           |
| :--------------------- | :----------------------------------------------------------------------------- |
| **Endpoints**          | The routes each service actually serves, from span attributes                  |
| **Versions**           | Which `service.version` values are live, and when each appeared                |
| **Deployment markers** | Deployment events you record, so a change can be lined up against a regression |

<Note>
  **Versions are how you connect a regression to a release.** If error rate
  moved at the same moment a new `service.version` appeared, you have your
  answer in one step. This requires setting `service.version` — it is the third
  most valuable resource attribute after name and environment.
</Note>

## Next

<CardGroup cols={3}>
  <Card title="Explore traces" icon="share-nodes" href="/guides/traces/overview">
    The spans the map is built from.
  </Card>

  <Card title="Infrastructure" icon="server" href="/guides/infrastructure/overview">
    Hosts, containers and Kubernetes beneath these services.
  </Card>

  <Card title="Zero-code instrumentation" icon="wand-magic-sparkles" href="/zero-code/overview">
    Fill the gaps without changing code.
  </Card>
</CardGroup>
