OpenTelemetry
A vendor-neutral open standard for collecting metrics, logs, and traces from applications. Provides SDKs and a collector that ships telemetry to any observability backend.
What is OpenTelemetry?
In short
OpenTelemetry (often shortened to OTel) is a vendor-neutral open standard, hosted by the CNCF, for generating and collecting telemetry data from software: traces, metrics, and logs. It gives you one set of SDKs, one wire protocol (OTLP), and one collector so your application code stays the same whether you send that data to Datadog, Grafana, Jaeger, Honeycomb, or any other backend.
What OpenTelemetry actually is
OpenTelemetry is two things at once: a specification and a set of implementations. The specification defines what a trace, a span, a metric, and a log record look like, and how they are encoded on the wire. The implementations are language SDKs (Go, Java, Python, JavaScript, .NET, Rust, and more) plus a standalone service called the Collector.
Before OpenTelemetry, every observability vendor shipped its own agent and its own SDK. If you instrumented your code with the Datadog tracer and later wanted to move to Grafana, you ripped out and rewrote the instrumentation. OpenTelemetry breaks that lock-in. You instrument once against the OTel API, and you choose where the data goes by swapping an exporter, not by rewriting your app.
It is the result of merging two earlier projects, OpenTracing and OpenCensus, in 2019. Today it is the second most active CNCF project after Kubernetes, and nearly every major observability vendor accepts its native protocol, OTLP.
How it works under the hood
The three signals are traces, metrics, and logs. A trace is the story of one request as it moves through your services. It is made of spans, where each span records a unit of work with a start time, a duration, and key-value attributes like http.status_code or db.statement. Spans carry a trace ID and a parent span ID, so the backend can stitch them into a tree even when they came from ten different services.
Context propagation is the glue. When service A calls service B, the OTel SDK injects the trace ID and span ID into the outgoing HTTP headers (the W3C traceparent header). Service B reads those headers and continues the same trace. This is what lets you follow a single user request across a whole distributed system.
In your code, the API layer creates spans and records measurements. The SDK batches them and hands them to an exporter, which serializes to OTLP (a Protobuf format over gRPC or HTTP) and ships them out. Most teams do not export straight to a vendor. They send to the OpenTelemetry Collector, a separate process that receives telemetry, runs it through processors (batching, sampling, dropping noisy attributes, redacting PII), and then fans it out to one or more backends.
When to use it and the trade-offs
Reach for OpenTelemetry when you run more than a couple of services, when you want to avoid being locked to one observability vendor, or when you need a single consistent way to instrument apps written in different languages. Auto-instrumentation libraries can wire up popular frameworks like Express, Flask, Spring, and gRPC with almost no code changes, which makes the on-ramp cheap.
The main cost is operational. Running and tuning the Collector is real work, and naive setups generate huge volumes of span data that get expensive to store. Most teams turn on sampling, often tail-based sampling in the Collector, so they keep the interesting traces (errors, slow requests) and drop the boring ones. Cardinality on metric attributes is another trap; a label like user_id can explode your time series count.
Maturity also varies by signal and language. Tracing is stable across most SDKs. Metrics are stable in the major languages. Logs reached stability later and the bridge from existing logging libraries is still uneven in some ecosystems. Check the status page for your specific language before betting on a signal.
A concrete example
Picture a checkout flow: a browser hits an API gateway, which calls a cart service, which calls a payments service, which writes to Postgres. With OTel auto-instrumentation on each service, the gateway starts a trace and a traceparent header rides along on every internal call.
When a customer reports that checkout was slow, you open the trace in your backend and see a waterfall: the gateway took 40ms, the cart service 30ms, but the payments service span shows a 2.1 second database query against Postgres. The slow span carries the exact SQL statement as an attribute, so you know which query to fix without guessing or adding more logging. That single, end-to-end view across four services is the payoff OpenTelemetry is built to deliver.
Where it is used in production
Shopify
Standardized telemetry across thousands of services on OpenTelemetry to unify tracing during Black Friday-scale traffic.
Grafana (Tempo, Mimir, Loki)
Ingests OTLP natively, so OTel traces, metrics, and logs flow straight into the Grafana stack without proprietary agents.
Datadog
Accepts OTLP and ships an OTel-compatible exporter, letting customers instrument with OTel and still use Datadog's UI.
Microsoft Azure Monitor
Built its Application Insights distro on OpenTelemetry, making OTel the recommended way to instrument apps on Azure.
Frequently asked questions
- What is the difference between OpenTelemetry and Prometheus?
- Prometheus is a metrics database and scraping system; it only handles metrics. OpenTelemetry is a broader standard that covers traces, metrics, and logs and is vendor-neutral about storage. They work together: OTel can produce metrics and the Collector can expose or forward them to Prometheus, which stores and queries them.
- Is OpenTelemetry free?
- Yes. OpenTelemetry is open source under the Apache 2.0 license and hosted by the CNCF. The SDKs and Collector cost nothing. What you pay for is the backend that stores and visualizes the data, whether that is a self-hosted tool like Jaeger or Grafana or a commercial vendor like Datadog or Honeycomb.
- What is OTLP?
- OTLP is the OpenTelemetry Protocol, the native wire format for sending telemetry. It encodes traces, metrics, and logs as Protobuf and transports them over gRPC or HTTP. Almost every modern observability backend can receive OTLP directly, which is what makes switching vendors a config change instead of a rewrite.
- Do I need the OpenTelemetry Collector?
- No, you can export directly from your app's SDK to a backend. But the Collector is recommended in production because it centralizes batching, sampling, attribute filtering, and PII redaction, and it lets you change backends without redeploying your services.
- What are traces, metrics, and logs in OpenTelemetry?
- Traces follow a single request across services and are made of spans. Metrics are numeric measurements over time, like request rate or memory usage. Logs are timestamped text or structured records of discrete events. OpenTelemetry can correlate all three using shared identifiers like the trace ID, so a log line can link back to the exact trace it belongs to.
Learn OpenTelemetry hands-on
This page explains the idea. The full lesson lets you step through the ring as servers join and leave, read the implementation, and check yourself with a quiz. It is one of 760+ lessons in the System Design Masterclass, from your first API call to distributed consensus. Eleven Foundation lessons are free, no signup. Lifetime access is ₹499 in India or $7.99 worldwide, one payment, no subscription.
Related lessons
Lessons that touch on OpenTelemetry as part of a larger topic.
Span IDs
Individual operations within a trace, each span is one unit of work with a start time, duration, and parent
intermediate · observability monitoring
Distributed Context Propagation
Passing trace context, baggage, and metadata across service boundaries, the glue of distributed tracing
intermediate · observability monitoring
Baggage
Custom key-value pairs that travel with the trace context, carrying business data through your distributed system
intermediate · observability monitoring
LLM Observability and Tracing: Seeing Inside a Nondeterministic System
An LLM app fails behind a 200 OK: right status, wrong answer. Capture the rendered prompt, token split, and per-step latency on one trace id.
ml-advanced · llm genai ops
See also
Related glossary terms you might want to look up next.
Distributed Tracing
Tracking a request as it flows through multiple services in a distributed system. Each service adds its trace, creating a full picture of the request journey.
Metrics
Numerical measurements collected over time that describe system behavior: request rate, error rate, latency percentiles, CPU utilization. Prometheus is the standard collector.
Observability
The ability to understand a system's internal state from its external outputs. Built on three pillars: metrics, logs, and traces.
Health Check
An endpoint or mechanism that reports whether a service is running and healthy. Load balancers use health checks to route traffic away from unhealthy instances.
Logging
Recording discrete events with timestamps, severity levels, and context. Structured logs (JSON) are searchable; unstructured logs (plaintext) are not. Ship them to a central system.
Alerting
Automatically notifying engineers when metrics cross predefined thresholds. Good alerts are actionable, not noisy. PagerDuty and Opsgenie route alerts to the right on-call person.