What Is Grafana in OpenTelemetry?
A plain-English guide to how OpenTelemetry creates and moves your telemetry, how Grafana turns it into charts, traces, and alerts you can actually read, and how the two fit together without being the same thing.
Imagine a television broadcast. A camera crew films an event, a transmitter sends the signal through the air, and a television in your living room shows you the picture. Nobody confuses the camera with the television. Each has its own job, and a good picture needs both.
Observability works in a very similar way. Your applications produce raw signals about what they are doing: traces, metrics, and logs. OpenTelemetry is the standard camera and transmitter. It creates the signals and carries them out of your programs. But a pile of raw signals is not something a person can look at. You need a screen. For many teams, that screen is Grafana.
The question “What is Grafana in OpenTelemetry?” is common, and it contains a small trap. Grafana is not a part of OpenTelemetry. It is a separate, popular tool that displays and explores the data that OpenTelemetry produces. In this guide, you will learn exactly where Grafana fits, which pieces of the Grafana family do which jobs, how data gets from your code to a Grafana panel, and how to avoid the mistakes that make dashboards slow, expensive, or misleading. No prior knowledge is needed. Every new word is explained the first time it appears.
1What Is Grafana in OpenTelemetry?
Grafana is the window you look through. OpenTelemetry is everything that puts the view behind the glass.
What Grafana is
Grafana is an open-source tool for visualizing and exploring data. You connect it to places where data is stored, you write questions called queries, and Grafana draws the answers as charts, tables, maps, and gauges on pages called dashboards. It can also send you a message when the data crosses a limit you care about, which is called alerting. Grafana is made by a company called Grafana Labs, and there is also a hosted version, Grafana Cloud, that runs it for you.
What OpenTelemetry is
OpenTelemetry, often shortened to OTel, is an open standard and a set of tools for creating and moving telemetry. It gives your code a common way to describe what it is doing, and a common wire format, called OTLP, to send that description onward. It deliberately does not include a place to store the data or a screen to look at it.
So where does Grafana fit?
Grafana sits at the far end of the journey. OpenTelemetry produces and delivers. Storage systems keep. Grafana shows. In a typical setup, data created by the OpenTelemetry SDK travels through a Collector into storage systems, and Grafana then reads from those storage systems to draw your dashboards. Grafana never talks to your application directly.
Think of a newspaper. Reporters gather facts, which is like the OpenTelemetry SDK. Printing presses and delivery vans move the pages, which is like the Collector and OTLP. The archive keeps old editions, which is like the storage systems. The reader’s eyes and the page layout are like Grafana. You can change the printing press without changing how readers enjoy the paper, and you can redesign the layout without retraining the reporters.
Whenever you are confused, ask “Is this about making and moving data, or about looking at data?” The first belongs to OpenTelemetry. The second belongs to Grafana.
2Why You Need Both: The Problem Each One Solves
Two tools exist because two different problems exist. Understanding the split makes every later decision easier.
Problem one: getting data out of programs
Before OpenTelemetry, each monitoring product had its own library for collecting data from your code. If you used Product A, your code was full of Product A calls. Switching meant rewriting. OpenTelemetry solves this: you instrument once, and you can send the data to almost any destination.
Problem two: understanding data
Even when data is collected, a person cannot read millions of raw records. They need charts that show trends, tables that rank problems, links that jump from a symptom to a cause, and alerts that wake the right person at the right time. This is the problem Grafana solves. It does not care how the data was made, as long as it can read it from a storage system.
| Question | OpenTelemetry | Grafana |
|---|---|---|
| Main job | Create and move telemetry | Visualize, explore, and alert on telemetry |
| Runs where? | Inside your apps (SDK) and beside them (Collector) | As a separate web service that people open in a browser |
| Stores data? | No, only passes it along | Mostly no, it reads from other stores |
| Who uses it? | Developers and platform engineers | Developers, operators, managers, and support staff |
| Can be replaced by? | Vendor-specific agents (with lock-in) | Other dashboard tools, or vendor consoles |
A kitchen has cooks and a dining room. The cooks prepare food in a standard way that every restaurant understands, and the dining room presents it beautifully to guests. A guest can change tables, and the cooks never notice. A cook can change recipes, and the guest only notices a better meal.
The benefit of keeping them separate
Because the two are separate, you can mix and match. You can send OpenTelemetry data to Grafana-based storage today and to a different vendor tomorrow, and your instrumentation does not change. You can also show data from non-OpenTelemetry sources, such as cloud monitoring services and databases, on the same Grafana dashboard as your OpenTelemetry data.
3Core Vocabulary: The Words You Need
A small set of words appears in every conversation about Grafana and OpenTelemetry. Learn them once, and the rest of the guide will be easy.
| Term | Plain meaning | Example |
|---|---|---|
| Telemetry | Data that a system reports about itself | Response times, error counts, log lines |
| Signal | A type of telemetry | Traces, metrics, logs |
| SDK | The OpenTelemetry library inside your application | The Java or Python SDK |
| OTLP | The standard wire format for sending telemetry | Data sent to port 4317 or 4318 |
| Collector | A separate program that receives, changes, and forwards telemetry | The OpenTelemetry Collector |
| Backend | A system that stores telemetry and answers queries | Tempo, Loki, Prometheus |
| Data source | A connection from Grafana to a backend | A Prometheus data source |
| Query | A question you ask a data source | “Average latency of the order service in the last hour” |
| Panel | One chart or table on a dashboard | A line chart of requests per second |
| Dashboard | A page that holds many panels | “Order service health” |
| Alert rule | A saved question plus a condition that triggers a message | “Error rate above 5 percent for 5 minutes” |
Three query languages you will hear about
PromQL
The language of Prometheus-style metric stores. It selects metric series and applies functions such as rate and average.
LogQL
The language of Loki. It selects log streams by labels and then filters or counts the lines inside them.
TraceQL
The language of Tempo. It finds traces and spans by their properties, such as duration, status, or attributes.
Grafana does not invent one language for everything. It speaks the language of each backend. That is a feature, since each language is designed for the shape of its data.
4The Big Picture: From Your Code to a Grafana Panel
The whole system fits in one picture. Learn it well, because every other chapter zooms into one corner of it.
flowchart LR
APP["Your Application with OpenTelemetry SDK"] -- "OTLP" --> COL["Collector or Grafana Alloy"]
COL --> TP["Tempo (traces)"]
COL --> LK["Loki (logs)"]
COL --> MM["Mimir or Prometheus (metrics)"]
TP --> GF["Grafana"]
LK --> GF
MM --> GF
GF --> USER["Engineer in a browser"]
Reading the picture
On the left, your application uses the OpenTelemetry SDK to create traces, metrics, and logs. It sends them using OTLP to a Collector, or to Grafana Alloy, which is Grafana’s own distribution of the Collector. The Collector sorts the data and sends each signal to the right backend. On the right, Grafana connects to those backends and draws what an engineer asks to see.
Create
The SDK records spans, measurements, and log records inside your running program.
Carry
An exporter sends the data in the OTLP format to a Collector or directly to a compatible backend.
Route
The Collector batches, cleans, and sends each signal to the proper storage system.
Keep
Each backend stores its kind of data and builds indexes so queries are fast.
Show
Grafana sends queries to the backends and draws the results as panels and alerts.
It is like a water system. Rain falls into collecting pipes at each house (the SDK). Pipes join into larger mains (the Collector). Reservoirs store the water (the backends). The tap in your kitchen is Grafana. You never drink straight from the rain, and you never go to the reservoir with a cup. The taps make it usable.
Do not expect to point Grafana at an OpenTelemetry SDK and see data. Grafana always needs a backend in the middle that holds the data. Without a backend, there is nothing for Grafana to ask.
5Meet the Grafana Family
When people say “Grafana” they sometimes mean one thing and sometimes the whole family. Here is who is who.
Grafana
The web application with dashboards, an exploration screen, and alerting. It reads data from many sources and stores only its own settings and dashboards.
Tempo
A trace storage backend that accepts OTLP and keeps traces cheaply in object storage. You search it with TraceQL.
Loki
A log storage backend that indexes labels and not the full text, which keeps it light. It can receive logs in OTLP format. You search it with LogQL.
Mimir
A scalable store for Prometheus-style metrics, compatible with PromQL. Plain Prometheus is a common alternative for smaller systems.
Pyroscope
A store for continuous profiles, which show which functions use the most CPU or memory over time.
Grafana Alloy
Grafana’s distribution of the OpenTelemetry Collector, with extra support for Prometheus-style collection. It receives and forwards telemetry.
Beyla
A tool that uses a Linux kernel feature called eBPF to observe programs without changing their code. This work has been moving toward the OpenTelemetry project’s own eBPF effort.
Faro
A web SDK that collects telemetry from users’ browsers, built with OpenTelemetry ideas, so that front-end data can be viewed next to the back-end.
The “LGTM” shorthand
People often say LGTM stack, which stands for Loki, Grafana, Tempo, and Mimir. It is a short way to describe the open-source set of tools for logs, dashboards, traces, and metrics. A ready-made single-container version for local learning exists, which is helpful if you want to try everything on a laptop.
You do not have to use the whole family. Grafana works with many non-Grafana backends, and the Grafana backends work with many tools besides Grafana. They fit together nicely, but they are not tied.
6Data Sources: How Grafana Reads Data
Grafana is mostly a very good question-asker. Understanding data sources is the key to understanding what it can and cannot do.
What a data source is
A data source is a saved connection from Grafana to a backend. It holds the address, the login details, and settings such as which tenant to use. Once a data source exists, a panel can send queries to it and show the answer. One dashboard can use many data sources at the same time, so a single page can show metrics from Prometheus, logs from Loki, and database numbers side by side.
flowchart TB
GF["Grafana Server"] -- "PromQL" --> PR["Prometheus or Mimir data source"]
GF -- "LogQL" --> LO["Loki data source"]
GF -- "TraceQL" --> TE["Tempo data source"]
GF -- "Cloud API" --> CW["Cloud monitoring data source"]
GF -- "SQL" --> DB["Database data source"]
PR --> GF
LO --> GF
TE --> GF
CW --> GF
DB --> GF
The important consequence
Grafana does not keep your telemetry. It asks the backend for it every time a panel loads. This means that storage costs, retention, and speed are decided by the backend. It also means that if the backend is down, your dashboards are empty even though Grafana itself is fine.
| Data source | Holds | Query language |
|---|---|---|
| Prometheus or Mimir | Metrics | PromQL |
| Loki | Logs | LogQL |
| Tempo | Traces | TraceQL, plus search by trace ID |
| Pyroscope | Profiles | Profile queries |
| Cloud monitoring services | Cloud metrics and logs | Each service’s own query style |
| SQL databases | Business and application data | SQL |
A librarian does not write the books, and does not own them either. She knows many libraries, speaks the language of each catalog, and brings you what you ask for. If a library closes, she cannot bring its books. Grafana behaves like that librarian for your data.
Give data sources clear names, such as “prod-metrics” and “prod-traces”. A dashboard that points to the wrong environment is one of the most common and most confusing mistakes.
7How a Dashboard Loads: Inside Grafana
Let us follow what happens between the moment someone opens a dashboard and the moment they see the charts.
sequenceDiagram
participant U as Engineer Browser
participant G as Grafana Server
participant P as Prometheus Data Source
participant L as Loki Data Source
U->>G: Open dashboard Order Service Health
G->>G: Load dashboard definition and variables
G->>P: Query request rate as PromQL
G->>L: Query error logs as LogQL
P-->>G: Time series result
L-->>G: Log lines result
G-->>U: Panels drawn with fresh data
Note over U,G: Repeats on every refresh interval
Step by step
First, the browser asks the Grafana server for the dashboard. The server loads the dashboard definition, which is a saved description of the panels, their queries, and the time range. It also fills in variables, which are drop-down choices such as environment or service name. Next, the server sends one query per panel to the matching data source. The data sources answer, and the server hands the results to the browser, which draws the charts. When auto-refresh is on, the whole round repeats every few seconds or minutes.
This explains a common surprise: a dashboard with forty panels sends forty or more queries every time it refreshes. If each query is heavy, the backend works hard, and the dashboard feels slow. Good dashboards keep queries light and the panel count reasonable.
Imagine a restaurant host who takes a table’s order of forty dishes and sends each to a different kitchen station. The table waits for the slowest dish. A dashboard waits for its slowest query in much the same way.
A longer refresh interval and a shorter time range are the cheapest ways to make a heavy dashboard calmer. Most teams do not need five-second refresh on every page.
8Getting OpenTelemetry Data Into Grafana Backends
Grafana can only show what the backends hold. So the real question is how OTLP data reaches Tempo, Loki, and a metrics store.
Option one: through a Collector or Alloy
The most common design places a Collector between your applications and the backends. Your SDKs send OTLP to the Collector. The Collector adds helpful labels, groups data into batches, and forwards each signal to its own backend. Grafana Alloy is a popular choice here, because it understands OTLP and also Prometheus-style scraping in the same program. A plain OpenTelemetry Collector works just as well, since the Grafana backends accept standard formats.
Option two: directly from the SDK
Modern Grafana backends accept OTLP directly. Tempo accepts OTLP traces. Loki can accept OTLP logs through a dedicated endpoint. Prometheus-compatible stores such as Mimir, and recent Prometheus versions when enabled, can accept OTLP metrics. So a small system could skip the Collector. It is simple, but you lose a central place to filter, protect, and reroute data, so most production systems keep the Collector.
| Signal | Backend | How it arrives | One thing to remember |
|---|---|---|---|
| Traces | Tempo | OTLP over gRPC or HTTP | Each trace is stored whole, found by ID or by search |
| Logs | Loki | OTLP log endpoint, or a Loki exporter | Selected resource attributes become index labels |
| Metrics | Mimir or Prometheus | OTLP endpoint, or remote write | Metric names and units may be translated to Prometheus style |
| Profiles | Pyroscope | Its own agents or an Alloy component | Linked to traces by shared labels |
flowchart LR
S1["Service A SDK"] -- "OTLP" --> AL["Alloy or Collector"]
S2["Service B SDK"] -- "OTLP" --> AL
S3["Service C SDK"] -- "OTLP" --> AL
AL -- "batch and add labels" --> AL
AL -- "traces" --> T["Tempo"]
AL -- "logs" --> L["Loki"]
AL -- "metrics" --> M["Mimir"]
A mail sorting center receives letters from many mailboxes and sends each to the right city. Houses could deliver their own letters, and it might work for a tiny town. A busy country needs the sorting center.
Settings differ between versions of Tempo, Loki, Mimir, and Alloy. Always check the current documentation of the exact version you run for endpoint paths and configuration names, since this guide avoids version-specific details on purpose.
9Traces in Grafana: Reading a Waterfall
A trace is the story of one request. Grafana, with Tempo behind it, turns that story into a picture you can read in a minute.
What you see
A trace is a group of spans. Each span is one timed step, such as “handle checkout” or “query the database”. Spans have parents and children, which show which step caused which. Grafana draws them as a waterfall: a list of horizontal bars where the left edge shows when a step started and the bar length shows how long it lasted. A long bar is a slow step. A bar with many small children shows a step that makes many calls.
Finding a trace
There are three common ways. You can paste a trace ID, which you might have copied from a log line or an error message. You can search with TraceQL, for example by asking for traces from one service where the duration is over a limit or the status is an error. Or you can follow a link from a log line, a metric point, or a service map. Good teams practice the third way the most, because it starts from a symptom and lands in a cause.
flowchart TB
R["Span: POST checkout - 820 ms"] --> A["Span: validate cart - 25 ms"]
R --> B["Span: charge payment - 700 ms"]
R --> C["Span: send receipt - 60 ms"]
B --> B1["Span: call bank API - 640 ms"]
B --> B2["Span: write payment row - 40 ms"]
In the tree, the root span took 820 milliseconds. The biggest child, charging the payment, took 700. Inside it, calling the bank took 640. So the slowness is in the bank call, not in your own database. A waterfall makes this obvious in seconds, while a pile of logs might take an hour.
The example numbers above are made up for teaching. Real traces vary, and the same step can be fast one minute and slow the next.
Service graph and span metrics
Tempo can also be set up to produce extra data from the spans it sees, using a component often called the metrics generator. It creates span metrics, which are request counts, error counts, and duration summaries per service and operation, and a service graph, which is a map of which services call which. These appear in Grafana as charts and a node map, and they let you start from the big picture before diving into one trace.
A trace waterfall is like a stopwatch record from a relay race. Each runner has a start and a finish, and you can see exactly who held up the team. The service graph is the map of the whole racetrack.
10Metrics in Grafana: Counting and Measuring Over Time
Metrics are numbers measured again and again. They are the cheapest signal to store and the best one for spotting trends.
The three metric shapes you will chart
Only goes up
Total requests served, total errors. You rarely chart the raw total. You chart its rate, meaning how fast it grows per second.
Goes up and down
Current memory use, queue length, temperature. You chart the value as it is.
A spread of values
Request durations grouped into buckets. You use it to chart percentiles such as the slowest five percent of requests.
Why percentiles matter
An average hides pain. If ninety-nine requests take one tenth of a second and one takes ten seconds, the average looks fine, but one user is miserable. A percentile such as the ninety-fifth tells you the time under which ninety-five percent of requests finish. Histograms make these charts possible, which is why OpenTelemetry histograms are valuable.
A note on names
OpenTelemetry names metrics with dots, such as http.server.request.duration. Prometheus-style stores prefer underscores and often add unit suffixes. When OTLP metrics enter such a store, names and some labels are usually translated. So the name you wrote in code may look slightly different in Grafana. Settings control this behavior, and defaults have changed across versions, so check what your own system does before building dashboards.
A car dashboard has an odometer (a counter that only grows), a fuel gauge (a gauge that moves both ways), and, if you imagine a recorded history of speeds sorted into bands, something like a histogram. You would not judge a trip only by average speed, because a few terrifying moments matter.
Start every service dashboard with the same three questions: how many requests, how many failures, and how slow. Teams call these rate, errors, and duration.
11Logs in Grafana: Reading the Diary
Logs are the detailed diary of your system. Loki and Grafana make that diary searchable without making it expensive.
How Loki thinks
Many log systems index every word, which is powerful but costly. Loki takes a lighter path. It indexes only a small set of labels, such as service name, environment, and namespace, and stores the log text in compressed chunks. When you search, you first pick labels to narrow down the streams, and then filter the text inside them. This keeps storage cheap, but it means that good labels are essential.
Labels versus the log body
A label should have few distinct values, like a service name or a level. A value that is unique for every request, such as a user ID or a trace ID, must not become a label, because it creates a huge number of tiny streams and hurts performance. Such values belong inside the log line or in what Loki calls structured metadata, which is stored beside the line without being indexed as a label.
| Good as a label | Bad as a label | Why |
|---|---|---|
| Service name | User ID | Few services, millions of users |
| Environment | Request ID | Unique every time |
| Log level | Full URL with query | Nearly unlimited variations |
| Namespace or region | Trace ID | Unique per request, better kept as structured metadata |
What OpenTelemetry adds
OpenTelemetry log records carry fields such as severity, body, resource attributes, and, when logged inside a span, the trace ID and span ID. When logs arrive in Loki through OTLP, a chosen set of resource attributes become labels and the rest become structured metadata. The trace ID that rides along is what makes the jump from a log line to a trace possible, which is the topic of the next chapter.
Loki’s label index is like the spines of binders on a shelf: “Kitchen, March”. You quickly pick the right binder, then flip through the pages. Indexing every word would be like writing a giant dictionary for every binder, helpful but heavy.
Too many labels is the classic Loki mistake. It shows up as slow queries and rising bills. Keep labels few and stable.
12Correlation: Jumping Between Signals
The greatest power of Grafana with OpenTelemetry is not any single chart. It is the ability to jump from one signal to another about the same event.
Three links worth setting up
Metric to trace
Some histogram points can carry an exemplar, which is a sample reference holding the ID of one real trace that produced that measurement. In Grafana you can see exemplars as dots on a chart and click one to open the trace.
Log to trace
Because log records carry a trace ID, Grafana can detect it with a setting often called derived fields and show a link beside the log line that opens the trace.
Trace to logs and metrics
On the Tempo data source you can configure links so that a span offers a button to show the logs of that same service around that same time, or related metrics.
flowchart LR
M["Metric chart shows slow spike"] -- "exemplar link" --> T["Trace waterfall"]
T -- "trace to logs" --> L["Logs of the slow span"]
L -- "derived field on trace ID" --> T
T -- "trace to metrics" --> M
What makes it work
All three links depend on shared identifiers and shared names. The trace ID must be present in the log record. The service name must be spelled the same way in traces, logs, and metrics, so that Grafana can narrow a log search to the right service. And the time must be roughly the same across systems. If one service names itself “checkout” in traces and “checkout-svc” in logs, the link finds nothing.
Think of a library where every book has the same catalog number printed in the book, on the shelf label, and in the computer. You can start from any of them and find the others. If the number were missing or typed differently in one place, the chain breaks.
Settle on one naming rule for service names early, and let OpenTelemetry’s resource attributes supply it everywhere. Correlation then comes almost for free.
13Designing Dashboards That People Actually Use
Anyone can make a dashboard. Making one that helps at three in the morning is a skill.
Start with a question
Every dashboard should answer one clear question, such as “Is the checkout service healthy?” or “Where is the money spent?” A dashboard with no question becomes a wall of charts that nobody trusts. Write the question at the top, in the title or a text panel.
Order from general to specific
Put the most important health indicators at the top: request rate, error rate, and slow requests. Below them put the supporting detail, such as resource use and dependency health. Place links at the bottom or side that lead to deeper dashboards and to trace and log exploration.
Use variables and consistency
Variables let one dashboard serve every service and environment. Instead of copying a dashboard thirty times, you choose a service from a drop-down. Keep colors, units, and time ranges consistent, so that a person can read any dashboard in your company the same way.
Keep dashboards as managed files
Dashboards are stored as structured text, which means they can be kept in version control, reviewed, and deployed automatically. This avoids the situation where someone edits a production dashboard by hand and nobody knows why it changed. Many teams provision dashboards from files so that the source of truth is clear.
| Do | Avoid |
|---|---|
| One question per dashboard | A single page for everything |
| Rates, errors, and durations first | Dozens of raw counters |
| Variables for service and environment | Copy-pasted dashboards |
| Clear units and thresholds | Unlabeled axes |
| Links to traces and logs | Dead-end charts |
A pilot’s cockpit shows the few instruments that matter most in front of the pilot, and puts rarely needed switches overhead. A good dashboard copies that thinking.
14Alerting: When Grafana Taps You on the Shoulder
Dashboards need a person to look at them. Alerts look for you, which is why they are the part that protects your sleep.
The pieces of Grafana alerting
Alert rule
A saved query and a condition, checked on a schedule. For example, the error rate is above a limit.
Contact point
Where a message goes, such as email, a chat tool, or a paging service.
Notification policy
Rules that choose which contact point receives which alert, by matching labels, and that group alerts together.
Silences and mute timings
Ways to pause alerts during planned work or off-hours.
Alert states
An alert instance moves through states. It is Normal when the condition is not met. It becomes Pending when the condition is met but has not lasted long enough, and Alerting when it has lasted for the required time. Special states exist for when data is missing or when the query itself failed. The waiting period prevents a single brief spike from paging someone.
stateDiagram-v2
[*] --> Normal
Normal --> Pending: "condition met"
Pending --> Alerting: "held for the waiting time"
Pending --> Normal: "condition cleared"
Alerting --> Normal: "condition cleared"
Alerting --> NoData: "query returns nothing"
NoData --> Normal: "data returns"
What to alert on
Alert on symptoms that users feel, such as high error rates or slow responses, rather than on every internal number. A high processor use may be fine, while a slow checkout is never fine. Each alert should point to a dashboard or a runbook, which is a written guide for what to do.
A smoke detector does not scream when you toast bread for one second. It waits to be sure, then it sounds. The Pending state is the same patience, and the contact point is the loud speaker.
Too many alerts teach people to ignore them. This is called alert fatigue. Remove or fix any alert that fires often and needs no action.
15Ways to Run Grafana: Cloud, Self-Hosted, and AWS
You can use Grafana without running a server, or you can run everything yourself. Each choice trades effort against control.
| Option | Who runs it | Good for | Cost of ownership |
|---|---|---|---|
| Grafana Cloud | Grafana Labs runs Grafana and the backends | Fast start, small teams | Usage-based bill, less operations work |
| Self-hosted open source stack | You run Grafana, Tempo, Loki, Mimir | Full control, data residency | Your time, storage, and upgrades |
| Managed on a cloud provider | The provider runs it for you | Teams already deep in one cloud | Provider pricing, some feature limits |
| Local single container | You, on a laptop | Learning and testing | Not for production |
An AWS example
On AWS, a common pairing is Amazon Managed Grafana for the screens and Amazon Managed Service for Prometheus for metrics. The Collector sends metrics to the managed Prometheus service using a remote write exporter with AWS request signing, which proves the sender’s identity using its cloud role. Grafana can also read directly from CloudWatch and X-Ray as data sources, which is useful when some of your data already lives there. Features and names evolve, so check the current AWS documentation when you design this.
flowchart LR
APP["Apps on containers"] -- "OTLP" --> COL["Collector"]
COL -- "remote write with signing" --> AMP["Managed Prometheus"]
COL -- "traces" --> XR["X-Ray or Tempo"]
AMP --> AMG["Managed Grafana"]
XR --> AMG
CW["CloudWatch"] --> AMG
Choosing between cloud and self-hosted is like choosing between eating at a restaurant and cooking at home. The restaurant is quick and costs per meal. Home cooking gives control and costs your time.
Because OTLP is a standard, you can start in a hosted service and move later by changing the Collector destination, without touching your application code.
16A Worked Example: Finding a Slow Checkout
Here is a made-up story to show every piece working together. The company, names, and numbers are invented for teaching.
The made-up shop: “Lantern Goods”
Lantern Goods sells candles online. Its checkout flow involves a web front end, a cart service, a payment service, and a receipt service. All four use OpenTelemetry and send OTLP to a Collector, which feeds Tempo, Loki, and a Prometheus-style store. The team uses Grafana to look at everything.
The alert
On a Friday evening, a Grafana alert fires: the ninety-fifth percentile of checkout duration has been above three seconds for ten minutes. It arrives in the team chat with a link to the checkout dashboard.
The dashboard
The dashboard shows request rate is normal, errors are low, but the slow percentile has jumped. The pattern started twenty minutes ago.
The exemplar
On the duration chart, the engineer clicks an exemplar dot on the spike and a trace opens in Grafana.
The waterfall
The waterfall shows the payment service spent most of the time in one child span, the call to an outside bank. Every other span is fast.
The logs
From that span, the engineer jumps to the logs of the payment service in the same time window. The log lines show repeated retry messages from the bank client.
The decision
The cause is an outside slowdown, not the shop’s own code. The team switches on a temporary shorter timeout and a friendly message for customers, and then contacts the bank.
In under ten minutes, the team moved from a vague symptom to a cause, using one tool and four connected views. Without correlation, they might have searched logs by hand across four services.
Notice that OpenTelemetry made the data consistent, and Grafana made it explorable. Neither alone would have delivered this speed.
17Resource Attributes and Labels: The Glue
Small naming choices made in your SDK decide whether Grafana feels magical or messy.
What resource attributes are
A resource in OpenTelemetry describes the thing producing telemetry: the service name, version, environment, host, and so on. These descriptions, called resource attributes, are attached to every trace, metric, and log from that service. They are the common thread across signals.
How Grafana backends use them
The backends turn some resource attributes into labels. In Prometheus-style stores, a special info-style metric can hold the full set while a few key ones become labels, depending on settings. In Loki, a configured list of attributes becomes index labels. In Tempo, attributes are searchable by TraceQL. Because the same service name is used everywhere, selecting “checkout” in a drop-down variable filters every panel the same way.
| Attribute | Purpose | Tip |
|---|---|---|
| service.name | Identifies the service | Required, and must be consistent |
| service.version | Shows which release is running | Great for comparing before and after a release |
| deployment.environment | Separates production, staging, and so on | Prevents mixing environments on a chart |
| host or pod name | Finds the specific machine | Keep out of metric labels if there are very many |
Resource attributes are like the name tag worn by every person at a conference. When everyone’s tag follows the same format, you can find anyone. When tags are written in ten styles, the crowd turns into a puzzle.
Set service name and environment in a shared startup configuration, not by hand in every service, so that mistakes cannot spread.
18Sampling and Volume: Deciding What to Keep
Storing every trace of every request gets expensive quickly. Sampling is the art of keeping what you need.
Two moments to decide
Head sampling decides when a trace begins, for example by keeping one in every ten. It is cheap and simple, but it cannot know yet whether the request will turn out to be slow or broken. Tail sampling waits until the trace is complete and then decides, so it can keep every error and every slow trace and only a small share of normal ones. It needs a Collector that holds traces in memory for a while, which costs more and is harder to scale.
Head sampling
- Simple and cheap
- Reduces load early, even inside the SDK
- Cannot see the final result
- May miss rare errors
Tail sampling
- Keeps all errors and slow traces
- Smarter, rule-based choices
- Needs memory and careful scaling
- All spans of a trace must reach the same Collector
Metrics keep the full picture
A useful trick is to generate span metrics before sampling happens, so that rate, error, and duration charts count every request even though only some traces are kept. The charts stay accurate, and the stored traces are the interesting examples.
A museum cannot display every object it owns, so a curator chooses. Head sampling is picking every tenth item from the storeroom at random. Tail sampling is a curator who looks at each piece first and keeps the rare and remarkable ones, while a ledger counts everything that ever arrived.
If you sample traces but compute rates from the stored traces, your numbers will be too low. Always compute rates from data collected before sampling.
19Security: Who Can See What
Telemetry often contains sensitive details, and Grafana is the window to all of it. Guard the window.
Sign-in and permissions
Grafana supports local accounts and sign-in through company identity systems. Prefer your company’s single sign-on so that people who leave lose access automatically. Grafana uses roles, such as viewer, editor, and administrator, and folders with permissions, so that a team sees only its own dashboards. Enterprise and cloud offerings add finer controls, such as team-based data source permissions, so check which features your edition has.
Protecting the data path
- Encrypt in transit. Use TLS between SDKs, Collectors, backends, and Grafana.
- Authenticate senders. Backends should accept data only from known senders, using tokens or signed requests.
- Separate tenants. Tempo, Loki, and Mimir support multiple tenants, so teams or environments can be isolated.
- Protect credentials. Data source passwords and API tokens belong in a secrets manager, not in dashboard files.
Keeping secrets out of telemetry
The best protection is not to collect sensitive data in the first place. Do not put passwords, card numbers, or personal details in span attributes, log lines, or labels. The Collector can remove or mask known sensitive fields before they reach storage, which gives you a safety net.
A building with a glass lobby still needs a front desk. Grafana is the lobby that lets people look into your systems, and sign-in, roles, and masking are the desk and the badges.
A public or shared dashboard link may expose real data to anyone who has it. Review sharing settings regularly and share only what is safe.
20Cost and Performance: Keeping the Bill and the Latency Down
Observability can quietly become one of the largest bills in a company. Knowing what drives cost lets you steer it.
What drives cost
Active series
Each unique combination of a metric name and its label values is a series. Adding a label with many values multiplies the series count. This is called high cardinality, and it is the most common cause of metric cost.
Volume and labels
The number of bytes ingested and the number of label combinations decide storage and query cost. Chatty debug logging in production is a classic waste.
Spans stored
The number of spans, and how many attributes each carries, drive trace storage. Sampling is the main control.
Heavy panels
Wide time ranges, expensive functions, and many refreshes make backends work harder, which raises compute cost.
Practical controls
- Remove labels you never filter by, especially anything unique per request.
- Drop noisy, low-value logs in the Collector before they are stored.
- Choose retention by signal: keep metrics longer than detailed traces and logs.
- Use recording rules or pre-aggregation so common heavy queries are computed once.
- Review the most expensive dashboards and queries every quarter.
Imagine a warehouse that charges by shelf space and by how often you ask the staff to fetch things. You would store fewer odd items, label shelves carefully, and avoid asking for everything every minute. Telemetry storage works much like that.
Most systems list the top series or label values by size. Look at that list first. A tiny number of labels usually causes most of the cost.
21Monitoring the Monitors
Your observability stack is itself a system that can fail. If it fails quietly, you will be blind exactly when you need sight.
What to watch
| Component | Questions to ask |
|---|---|
| SDKs | Are exports succeeding? Is data being dropped because queues are full? |
| Collector or Alloy | Is it receiving and sending at the expected rate? Is memory under control? Are there refused or failed sends? |
| Tempo, Loki, Mimir | Is ingestion keeping up? Are queries slow? Are limits being hit? Is storage healthy? |
| Grafana | Are data sources reachable? Are alert evaluations running on time? Are notifications being delivered? |
A heartbeat for alerting
A useful trick is an alert that is always firing on purpose, called a heartbeat or watchdog. It is sent to an outside service. If that service stops receiving the heartbeat, you know that your alerting pipeline has broken. Otherwise, a broken pipeline looks identical to a calm night.
Where the monitors should live
If your monitoring runs only inside the system it watches, a major outage can take both down together. For important production, keep a small independent path, such as a separate small stack or an external check, that can tell you the main one is gone.
A fire station needs its own fire alarm. A guard who falls asleep without anyone checking on them is worse than no guard, because everyone assumes the building is watched.
Silence is ambiguous. No alerts can mean everything is fine or that alerting has died. Build a way to tell the difference.
22Advantages, Disadvantages, and Trade-offs
Grafana is popular for good reasons, but it is not free of costs. A fair look at both sides will help you decide.
Advantages
- Reads from many sources, so one screen can show everything
- Works with OpenTelemetry through open standards, reducing lock-in
- Strong links between metrics, logs, and traces
- Flexible dashboards and a large community of shared examples
- Open-source core with hosted options for teams that prefer not to operate it
Disadvantages
- It needs backends, so a full stack means several systems to learn and run
- Dashboards can sprawl and become inconsistent without care
- Query languages differ per backend, which means more to learn
- Some advanced features depend on the edition or the hosted plan
- Poor labels or heavy queries can hurt cost and speed
Key trade-offs
| Choice | One side | Other side |
|---|---|---|
| Self-host or hosted | Control and data location | Less work and faster start |
| One vendor stack or mixed tools | Smooth integration | Freedom to choose the best tool for each signal |
| Keep everything or sample | Complete detail | Lower cost and faster queries |
| Many dashboards or few | Tailored views per team | Consistency and easier upkeep |
| Direct to backend or through a Collector | Fewer moving parts | Central control, safety, and rerouting |
Choosing a toolset is like choosing a kitchen. A full professional kitchen can cook anything but needs staff and cleaning. A small apartment kitchen is simple, and it limits what you can prepare. Neither is wrong. The right one matches how many meals you cook.
Grafana is a strong default, but it is not the only way to view OpenTelemetry data. Several other tools can read OTLP data too. The standard exists so that this choice stays open.
23Patterns and Anti-patterns
Teams keep rediscovering the same good habits and the same bad ones. Here are the ones that matter most.
Good patterns
Collector in the middle
Every SDK sends to a Collector, and only the Collector knows the backend addresses. Changing vendors becomes a single configuration change.
Overview then drill-down
Start with a fleet or service overview, then link to a service dashboard, then to traces and logs.
Dashboards as code
Keep dashboard definitions in version control and deploy them automatically.
Symptom-based alerts
Alert on what users feel, and link each alert to a dashboard and a runbook.
Anti-patterns
The wall of charts
One dashboard with eighty panels and no question. It loads slowly and answers nothing.
Unique values as labels
User IDs or request IDs used as labels, which explode series counts.
Alert on everything
Every metric has a threshold, and the team mutes the channel.
Hand-edited production dashboards
Nobody knows who changed what, and fixes vanish at the next deployment.
Good patterns are like tidy habits in a kitchen: labeled jars, a clean counter, knives in a block. Anti-patterns are the overflowing junk drawer. Both can hold the same items, but only one lets you find them in the dark.
24Best Practices and Common Mistakes
If you remember only a few pages of this guide, make them these.
Best practices
- Use OpenTelemetry for instrumentation and keep your code free of vendor-specific calls.
- Agree on resource attribute names, especially service name and environment, before building dashboards.
- Send all signals through a Collector so you can filter, protect, and reroute them in one place.
- Set up correlation links early, since they reward you on your first incident.
- Start every service dashboard with rate, errors, and duration, then add detail.
- Manage dashboards and alert rules as files in version control.
- Watch the health of the observability stack itself, with a heartbeat alert.
- Review costs and slow queries on a regular schedule.
Common mistakes
| Mistake | What happens | Better habit |
|---|---|---|
| Thinking Grafana stores the data | Surprise when data vanishes after a backend change | Understand retention at each backend |
| Inconsistent service names | Correlation links find nothing | Set names centrally |
| Showing only averages | Slow outliers are hidden | Chart percentiles |
| No time-range limit on heavy panels | Slow dashboards and big bills | Use shorter ranges and recorded queries |
| Sensitive data in attributes | Privacy risk across every dashboard | Mask in code and at the Collector |
| Forgetting the alert pipeline can break | Silent failure during outages | Heartbeat and an independent check |
Teach new team members using a real past incident and the dashboards that solved it. It is the fastest way to build the habit of moving between signals.
25Troubleshooting: When a Panel Shows No Data
The most common support question is “I send data, but Grafana shows nothing.” Follow the path from left to right and you will find the break.
flowchart TB
Q["Panel shows no data"] --> A{"Is the time range right?"}
A -- "no" --> A1["Widen or fix the range"]
A -- "yes" --> B{"Does the data source test pass?"}
B -- "no" --> B1["Check address and login and tenant"]
B -- "yes" --> C{"Does the same query work in Explore?"}
C -- "no" --> C1["Fix the query or label names"]
C -- "yes" --> D{"Is the backend receiving data?"}
D -- "no" --> E{"Is the Collector sending?"}
E -- "no" --> E1["Check exporter settings and errors"]
E -- "yes" --> E2["Check backend limits and auth"]
D -- "yes" --> F["Check dashboard variables and filters"]
Explaining the checklist
Begin with the simplest causes, because they are the most common. A time range that is too narrow or in the wrong place hides data. A data source with a wrong address, a missing tenant header, or an expired token fails the connection test. If the connection works, copy the query into the exploration screen and run it there. If it fails, the problem is the query, perhaps because a label was renamed during translation, such as a dot becoming an underscore. If the query works in Explore, then the dashboard variables or filters are likely too narrow.
If the backend truly has no data, move left. Ask whether the Collector is sending it, and look at the Collector’s own logs and metrics for refused or failed sends. If it is sending but the backend still has nothing, look at ingestion limits, authentication, and rate rules at the backend.
If a tap gives no water, you do not start by digging up the street. You check whether the tap is open, then the pipe under the sink, then the main valve, then the supplier. You move from the nearest, cheapest check to the farthest.
Name translation is a frequent trap. If a metric exists but you cannot find it by the name you wrote in code, search the metric list for part of the name, and check how your store translates dots, units, and suffixes.
26Real-World Examples
The following stories are invented to show typical situations. They are not reports about real companies.
Example one: a small startup moves fast
A five-person startup runs a handful of services. They send OTLP straight from the SDKs to a hosted Grafana service. They have no Collector to run and no storage to manage. Within a day they have service dashboards and trace search. Later, as traffic grows, they add a Collector so they can sample traces and hide sensitive fields. The application code never changes.
Example two: a large company keeps data at home
A company in a regulated field must keep telemetry inside its own network. A platform team runs Alloy, Tempo, Loki, and Mimir on its own clusters, with separate tenants for each business unit. Business units get their own folders in Grafana and see only their data. The platform team provides starter dashboards and alert templates so that every team begins with sound defaults.
Example three: a cloud-heavy team mixes sources
A team on a single cloud already uses managed services for databases and queues. They use managed Grafana and managed Prometheus, add the cloud’s monitoring service as a data source, and send their own OpenTelemetry traces and metrics through a Collector. One dashboard shows application traces beside the cloud’s database health, which makes slow queries easier to connect with their causes.
Example four: a mobile and web company watches the front end
A retail company wants to see what customers experience in the browser. They use a web telemetry library, such as Faro or the OpenTelemetry browser tools, to send page load timings and errors. Because the browser’s trace context is passed to the back-end calls, one trace in Grafana shows the click, the network call, and the server work together.
Different households use the same kitchen tools differently. Some cook for two, some for a hundred. The tools stay the same, and the setup scales to the family.
27Profiles and Browser Data: Two More Windows
Traces, metrics, and logs are the three classic signals. Grafana also helps you look at two extra kinds of evidence that fill common blind spots.
Continuous profiles
A profile shows which functions in your program use the most processor time or memory. A trace tells you that a step was slow. A profile tells you which lines of code inside that step were busy. Pyroscope stores profiles over time, and Grafana draws them as a flame graph, a stack of wide and narrow blocks where wide blocks are the hungry functions. When profiles and traces share labels such as service name, Grafana can offer a link from a slow span to the profile of the same time window. OpenTelemetry has been working on its own profiling signal, and its status may have changed since this was written, so check the current state before depending on it.
Browser and mobile data
Back-end telemetry only describes what happens on your servers. Customers feel the full path, including the network and their own device. A browser library such as Faro, or the OpenTelemetry browser tools, records page load times, errors, and user actions, and can pass the trace context to back-end calls. In Grafana, one trace can then begin in the browser and continue through your services, so you can tell whether slowness came from the page or from the server.
Which step is slow?
Answered by traces and their waterfall view.
Which code is slow?
Answered by profiles and flame graphs.
Is the user’s side slow?
Answered by browser or mobile telemetry.
How often does it happen?
Answered by metrics and their percentile charts.
A doctor uses a thermometer for a quick check, an X-ray to see inside, and a conversation to learn how you feel. Each tool answers a different question. Profiles are the X-ray of your program, and browser data is the conversation with the patient.
Add these extra signals only after your basic rate, errors, and duration dashboards are solid. They are powerful, but they also add cost and learning.
28A Gentle Adoption Roadmap
You do not need to build everything at once. A staged path lowers risk, and each stage gives value on its own.
Try it locally
Run an all-in-one learning setup on a laptop. Instrument one small program and watch data appear in Grafana. The goal is understanding, not production.
Agree on names
Decide service names, environment names, and the few resource attributes everyone must set. Write them down in a short guide.
Add a Collector
Place a Collector or Alloy between services and backends. Start with batching and basic labels, and add filtering later.
Build the first dashboards
For each service, make a rate, errors, and duration page with links to traces and logs. Store the definitions in version control.
Turn on alerts and correlation
Create a few symptom-based alerts with runbooks. Configure exemplars, derived fields, and trace-to-logs links.
Tune and protect
Add sampling, masking of sensitive fields, retention rules, and a heartbeat for the alert pipeline. Review cost every quarter.
Signs you are ready for the next stage
Move forward when the earlier stage is boring. If people still argue about service names, do not add sampling yet. If dashboards are not trusted, do not add more alerts yet. A stable base makes each new layer easier, and an unstable base makes every layer worse.
Learning to cook a banquet starts with boiling an egg. You do not buy a restaurant on the first day. Each small success teaches skills you will reuse in the next, bigger recipe.
Because OpenTelemetry keeps your instrumentation separate from your viewer, early choices are not locked in. If you later change backends or viewers, the work you put into instrumentation continues to pay off.
29Frequently Asked Questions
No. OpenTelemetry is an open standard and a set of tools for creating and moving telemetry. Grafana is a separate product for viewing and alerting. They work well together because Grafana’s backends accept OTLP and Grafana reads from them.
Grafana the dashboard application does not receive telemetry. The storage backends, such as Tempo, Loki, and Mimir, accept it, and Grafana then reads from them. Grafana Alloy can also receive OTLP and forward it.
No. You can use Grafana with Prometheus alone, or with a mix of non-Grafana backends. You can also use Grafana’s backends with other viewers. Choose by need.
Alloy is Grafana’s distribution of the Collector, with its own configuration style and extra components, including strong Prometheus support. Both can receive, process, and forward OTLP. Feature details change, so check current documentation.
Prometheus-style stores often translate OpenTelemetry names, replacing dots with underscores and adding unit or type suffixes. Settings control this, and defaults have evolved, so inspect the names in your own store.
Make sure logs carry the trace ID, which OpenTelemetry does when logging inside an active span. Then configure the log data source’s derived field or equivalent feature so that Grafana turns the trace ID into a link to the trace data source.
An exemplar is a sample reference attached to a metric point that holds the ID of one trace that contributed to it. Grafana can display exemplars as dots on a chart and open the trace when you click.
Mostly no. It stores dashboards, users, and settings. Telemetry lives in the backends, and retention is decided there.
Usually many panels, wide time ranges, heavy queries, or high-cardinality data. Reduce panels, shorten the range, lengthen refresh, and use pre-aggregated or recorded queries.
Yes. Grafana reads from many sources, including older Prometheus exporters and cloud services. OpenTelemetry simply gives you a vendor-neutral way to produce the data.
Run a local all-in-one setup on a laptop, instrument one small application, and build a rate, errors, and duration dashboard. Then add trace and log links. Doing it once, end to end, teaches more than reading.
Alert on user-facing symptoms, add waiting periods, group related alerts through notification policies, and remove alerts that need no action.
30Summary and Key Takeaways
Grafana is the screen, and OpenTelemetry is the camera and the cable. OpenTelemetry creates and carries traces, metrics, and logs in a common format. Backends such as Tempo, Loki, and Mimir or Prometheus keep that data. Grafana asks the backends questions and turns the answers into dashboards, exploration views, and alerts. Understanding this split keeps you from mixing up responsibilities, and it gives you freedom to change one part without rewriting another.
Key Takeaways
- Grafana is not part of OpenTelemetry. It visualizes and alerts on data that OpenTelemetry produces and backends store.
- Grafana reads from data sources and speaks each backend’s language: PromQL, LogQL, and TraceQL.
- A Collector or Alloy in the middle gives you one place to filter, protect, sample, and reroute telemetry.
- Consistent resource attributes, trace IDs in logs, and exemplars make jumping between signals possible.
- Keep labels few and stable, sample wisely, and design dashboards around questions to control cost and speed.
- Alert on user-facing symptoms, protect sensitive data, and watch the health of the monitoring stack itself.