<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Service graphs on Grafana Labs</title><link>https://grafana.com/docs/tempo/v2.2.x/metrics-generator/service_graphs/</link><description>Recent content in Service graphs on Grafana Labs</description><generator>Hugo -- gohugo.io</generator><language>en</language><atom:link href="/docs/tempo/v2.2.x/metrics-generator/service_graphs/index.xml" rel="self" type="application/rss+xml"/><item><title>Enable service graphs</title><link>https://grafana.com/docs/tempo/v2.2.x/metrics-generator/service_graphs/enable-service-graphs/</link><pubDate>Fri, 03 Apr 2026 19:43:06 +0000</pubDate><guid>https://grafana.com/docs/tempo/v2.2.x/metrics-generator/service_graphs/enable-service-graphs/</guid><content><![CDATA[&lt;h2 id=&#34;enable-service-graphs&#34;&gt;Enable service graphs&lt;/h2&gt;
&lt;p&gt;Service graphs are generated in Tempo and pushed to a metrics storage.
Then, they can be represented in Grafana as a graph.
You will need those components to fully use service graphs.&lt;/p&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;Cardinality can pose a problem when you have lots of services.
To learn more about cardinality and how to perform a dry run of the metrics generator, see the &lt;a href=&#34;../../cardinality/&#34;&gt;Cardinality documentation&lt;/a&gt;.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h3 id=&#34;enable-service-graphs-in-tempoget&#34;&gt;Enable service graphs in Tempo/GET&lt;/h3&gt;
&lt;p&gt;To enable service graphs in Tempo/GET, enable the metrics generator and add an overrides section which enables the &lt;code&gt;service-graphs&lt;/code&gt; generator.
For more information, refer to the &lt;a href=&#34;../../../configuration/#metrics-generator&#34;&gt;configuration details&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To enable service graphs when using Grafana Agent, refer to the &lt;a href=&#34;../../../configuration/grafana-agent/service-graphs/&#34;&gt;Grafana Agent and service graphs documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;enable-service-graphs-in-grafana&#34;&gt;Enable service graphs in Grafana&lt;/h3&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;Since Grafana 9.0.4, service graphs have been enabled by default. Prior to Grafana 9.0.4, service graphs were hidden
under the &lt;a href=&#34;/docs/grafana/latest/setup-grafana/configure-grafana/#feature_toggles&#34;&gt;feature toggle&lt;/a&gt; &lt;code&gt;tempoServiceGraph&lt;/code&gt;.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;Configure a Tempo data source&amp;rsquo;s service graphs by linking to the Prometheus backend where metrics are being sent:&lt;/p&gt;

&lt;div class=&#34;code-snippet code-snippet__mini&#34;&gt;&lt;div class=&#34;lang-toolbar__mini&#34;&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet code-snippet__border&#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-none&#34;&gt;apiVersion: 1
datasources:
  # Prometheus backend where metrics are sent
  - name: Prometheus
    type: prometheus
    uid: prometheus
    url: &amp;lt;prometheus-url&amp;gt;
    jsonData:
        httpMethod: GET
    version: 1
  - name: Tempo
    type: tempo
    uid: tempo
    url: &amp;lt;tempo-url&amp;gt;
    jsonData:
      httpMethod: GET
      serviceMap:
        datasourceUid: &amp;#39;prometheus&amp;#39;
    version: 1&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h2 id="enable-service-graphs">Enable service graphs&lt;/h2>
&lt;p>Service graphs are generated in Tempo and pushed to a metrics storage.
Then, they can be represented in Grafana as a graph.
You will need those components to fully use service graphs.&lt;/p></description></item><item><title>Estimate cardinality from traces</title><link>https://grafana.com/docs/tempo/v2.2.x/metrics-generator/service_graphs/estimate-cardinality/</link><pubDate>Fri, 03 Apr 2026 19:43:06 +0000</pubDate><guid>https://grafana.com/docs/tempo/v2.2.x/metrics-generator/service_graphs/estimate-cardinality/</guid><content><![CDATA[&lt;h2 id=&#34;estimate-cardinality-from-traces&#34;&gt;Estimate cardinality from traces&lt;/h2&gt;
&lt;p&gt;Cardinality can pose a problem when you have lots of services.
There isn&amp;rsquo;t a direct formula or solution to this issue.
The following guide should help estimate the cardinality that the feature will generate.&lt;/p&gt;
&lt;p&gt;For more information on cardinality, refer to the &lt;a href=&#34;../../cardinality/&#34;&gt;Cardinality&lt;/a&gt; documentation.&lt;/p&gt;
&lt;h3 id=&#34;how-to-estimate-the-cardinality&#34;&gt;How to estimate the cardinality&lt;/h3&gt;
&lt;p&gt;The amount of edges depends on the number of nodes in the system and the direction of the requests between them.
Let’s call this amount hops. Every hop will be a unique combination of client &#43; server labels.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A system with 3 nodes &lt;code&gt;(A, B, C)&lt;/code&gt; of which A only calls B and B only calls C will have 2 hops &lt;code&gt;(A → B, B → C)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;A system with 3 nodes &lt;code&gt;(A, B, C)&lt;/code&gt; that call each other (i.e., all bidirectional link) will have 6 hops &lt;code&gt;(A → B, B → A, B → C, C → B, A → C, C → A)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We can’t calculate the amount of hops automatically based upon the nodes,
but it should be a value between &lt;code&gt;#services - 1&lt;/code&gt; and &lt;code&gt;#services!&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If we know the amount of hops in a system, we can calculate the cardinality of the generated
&lt;a href=&#34;../&#34;&gt;service graphs&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&#34;code-snippet code-snippet__mini&#34;&gt;&lt;div class=&#34;lang-toolbar__mini&#34;&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet code-snippet__border&#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-none&#34;&gt;  traces_service_graph_request_total: #hops
  traces_service_graph_request_failed_total: #hops
  traces_service_graph_request_server_seconds: 3 buckets * #hops
  traces_service_graph_request_client_seconds: 3 buckets * #hops
  traces_service_graph_unpaired_spans_total: #services (absolute worst case)
  traces_service_graph_dropped_spans_total: #services (absolute worst case)&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Finally, we get the following cardinality estimation:&lt;/p&gt;

&lt;div class=&#34;code-snippet code-snippet__mini&#34;&gt;&lt;div class=&#34;lang-toolbar__mini&#34;&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet code-snippet__border&#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-none&#34;&gt;  Sum: 8 * #hops &amp;#43; 2 * #services&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;To estimate the number of metrics, refer to the &lt;a href=&#34;../../cardinality/&#34;&gt;Dry run metrics generator&lt;/a&gt; documentation.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

]]></content><description>&lt;h2 id="estimate-cardinality-from-traces">Estimate cardinality from traces&lt;/h2>
&lt;p>Cardinality can pose a problem when you have lots of services.
There isn&amp;rsquo;t a direct formula or solution to this issue.
The following guide should help estimate the cardinality that the feature will generate.&lt;/p></description></item><item><title>Service graph metrics queries</title><link>https://grafana.com/docs/tempo/v2.2.x/metrics-generator/service_graphs/metrics-queries/</link><pubDate>Fri, 03 Apr 2026 19:43:06 +0000</pubDate><guid>https://grafana.com/docs/tempo/v2.2.x/metrics-generator/service_graphs/metrics-queries/</guid><content><![CDATA[&lt;h1 id=&#34;service-graph-metrics-queries&#34;&gt;Service graph metrics queries&lt;/h1&gt;
&lt;p&gt;A collection of useful PromQL queries for service graphs.&lt;/p&gt;
&lt;p&gt;In most cases, users want to see a visual representation of their service graph. Grafana uses the service graph metrics created by Tempo and builds that visual for the user. However, in some cases, users may want to interact with the metrics that define that service graph directly. They may want to, for example, programmatically analyze how their services are interconnected and build downstream applications that use this information.&lt;/p&gt;
&lt;p&gt;To help with this, we&amp;rsquo;ve provided a collection of useful PromQL queries that can be used to explore service graph metrics.&lt;/p&gt;
&lt;h2 id=&#34;instant-queries&#34;&gt;Instant Queries&lt;/h2&gt;
&lt;p&gt;An instant query will give a single value at the end of the selected time range.
&lt;a href=&#34;https://prometheus.io/docs/prometheus/latest/querying/api/#instant-queries&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Instant queries&lt;/a&gt; are quicker to execute and it often easier to understand their results. We will prefer them in some scenarios:&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;../screenshot-serv-graph-instant-query.png&#34;
  alt=&#34;Instant query in Grafana&#34;/&gt;&lt;/p&gt;
&lt;h3 id=&#34;connectivity-between-services&#34;&gt;Connectivity between services&lt;/h3&gt;
&lt;p&gt;Show me the total calls in the last 7 days for every client/server pair:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;promql&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-promql&#34;&gt;sum(increase(traces_service_graph_request_server_seconds_count{}[7d])) by (server, client) &amp;gt; 0&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If you&amp;rsquo;d like to only see when a single service is the server:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;promql&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-promql&#34;&gt;sum(increase(traces_service_graph_request_server_seconds_count{server=&amp;#34;foo&amp;#34;}[7d])) by (client) &amp;gt; 0&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If you&amp;rsquo;d like to only see when a single service is the client:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;promql&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-promql&#34;&gt;sum(increase(traces_service_graph_request_server_seconds_count{client=&amp;#34;foo&amp;#34;}[7d])) by (server) &amp;gt; 0&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In all of the above queries, you can adjust the interval to change the amount of time this is calculated for. So if you wanted the same analysis done over one day:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;promql&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-promql&#34;&gt;sum(increase(traces_service_graph_request_server_seconds_count{}[1d])) by (server, client) &amp;gt; 0&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;range-queries&#34;&gt;Range queries&lt;/h2&gt;
&lt;p&gt;Range queries are nice for calculating service graph info over a time range instead of a single point in time.&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;../screenshot-serv-graph-range-query.png&#34;
  alt=&#34;Range query in Grafana&#34;/&gt;&lt;/p&gt;
&lt;h3 id=&#34;rates-over-time-between-services&#34;&gt;Rates over time between services&lt;/h3&gt;
&lt;p&gt;Taking two of the queries above, we can request the rate over time that any given service acted as the client or server:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;promql&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-promql&#34;&gt;sum(rate(traces_service_graph_request_server_seconds_count{server=&amp;#34;foo&amp;#34;}[5m])) by (client) &amp;gt; 0

sum(rate(traces_service_graph_request_server_seconds_count{client=&amp;#34;foo&amp;#34;}[5m])) by (server) &amp;gt; 0&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Notice that our interval dropped to 5m. This is so we only calculate the rate over the past 5 minutes which creates a more responsive graph.&lt;/p&gt;
&lt;h3 id=&#34;latency-percentiles-over-time-between-services&#34;&gt;Latency percentiles over time between services&lt;/h3&gt;
&lt;p&gt;These queries will give us latency quantiles for the above rate. If we were interested in how the latency changed over time between any two services we could use these. In the following query the &lt;code&gt;.9&lt;/code&gt; means we&amp;rsquo;re calculating the 90th percentile. Adjust this value if you want to calculate a different percentile for latency (e.g. p50, p95, p99, etc).&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;promql&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-promql&#34;&gt;histogram_quantile(.9, sum(rate(traces_service_graph_request_server_seconds_bucket{client=&amp;#34;foo&amp;#34;}[5m])) by (server, le))&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="service-graph-metrics-queries">Service graph metrics queries&lt;/h1>
&lt;p>A collection of useful PromQL queries for service graphs.&lt;/p>
&lt;p>In most cases, users want to see a visual representation of their service graph. Grafana uses the service graph metrics created by Tempo and builds that visual for the user. However, in some cases, users may want to interact with the metrics that define that service graph directly. They may want to, for example, programmatically analyze how their services are interconnected and build downstream applications that use this information.&lt;/p></description></item></channel></rss>