OTLP (OpenTelemetry Protocol) is the vendor-neutral protocol that OpenTelemetry uses to transmit telemetry between SDKs, collectors and backends. It defines Protobuf-encoded messages for traces, metrics and logs and carries them over gRPC (default port 4317) or HTTP (default port 4318), with well-defined retry, compression and response semantics.
What is OTLP?
OTLP, the OpenTelemetry Protocol, is the native wire protocol of OpenTelemetry. It specifies how telemetry data is encoded, transported and acknowledged between an application's SDK, an OpenTelemetry Collector and an observability backend. Because every OpenTelemetry SDK and the Collector speak OTLP, it has become the common language for moving traces, metrics and logs, and it is what makes switching or combining backends possible without re-instrumenting code.
The trace, metric and log signals are stable in the specification. A profiles signal is being developed in the same protocol family, so continuous profiling data can follow the same pipeline in the future.
Before OTLP, tracing systems such as Jaeger and Zipkin and the various metrics agents each used their own formats. The Collector can still receive many of those legacy formats and translate them, but OTLP is the format all signals converge on.
Transports, ports and endpoints
OTLP defines two transports. Both carry the same Protobuf data model, defined in the opentelemetry-proto repository.
| Aspect | OTLP/gRPC | OTLP/HTTP |
|---|---|---|
| Default port | 4317 | 4318 |
| Encoding | Binary Protobuf | Binary Protobuf or JSON (Protobuf JSON mapping) |
| Paths | gRPC services per signal (TraceService, MetricsService, LogsService) | /v1/traces, /v1/metrics, /v1/logs |
| Typical use | Service-to-collector traffic inside a cluster | Browsers, serverless, proxies and firewalls that only allow HTTP |
Both transports support gzip compression. The exporter's protocol is usually selected with the environment variable OTEL_EXPORTER_OTLP_PROTOCOL, whose values are grpc, http/protobuf and http/json. SDK defaults differ by language, so set it explicitly.
How an OTLP export works
- The SDK batches spans, metric data points or log records and groups them by resource (for example
service.name,k8s.pod.name) and instrumentation scope. - The exporter sends an export request to the configured endpoint.
- The receiver answers with success, a partial success that reports how many items were rejected and why, or an error.
- On retryable failures, such as gRPC
UNAVAILABLEor HTTP 429, 502, 503 and 504, the client retries with exponential backoff and honors any throttling hint the server sends.
Configuration example
An illustrative setup: applications export to a local Collector over gRPC, and the Collector forwards to a backend over HTTP.
# Application environment
OTEL_SERVICE_NAME=checkout
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317
OTEL_EXPORTER_OTLP_PROTOCOL=grpc
# Collector (excerpt)
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
exporters:
otlphttp:
endpoint: https://otlp.example.com
compression: gzip
With OTLP/HTTP, the SDK appends /v1/traces and the other signal paths to the base endpoint. If you use the signal-specific variables such as OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, you must provide the full URL including the path.
Why OTLP matters
- No lock-in: the same instrumentation can send to any OTLP-capable backend, or to several at once through a Collector.
- One pipeline for all signals: traces, metrics and logs share resource attributes, which keeps trace context and service identity consistent.
- Efficient transport: Protobuf with compression is compact, and batching keeps request counts low.
- Clear semantics: partial success and retry rules make data loss visible instead of silent.
Operating OTLP reliably
In production, OTLP traffic deserves the same care as any other critical data path. Encrypt it with TLS and authenticate exporters, for example with an API token in a header set through OTEL_EXPORTER_OTLP_HEADERS. Size batches so that a single request stays well below the receiver's maximum message size; gRPC servers commonly reject messages above a few megabytes. Give the Collector a sending queue and, where losing data during a restart is unacceptable, a persistent queue on disk. Finally, monitor the pipeline itself: the Collector exposes its own metrics for accepted, refused and failed items, and a rising refusal count is often the first sign of back pressure from the backend or of a misconfigured exporter.
Common mistakes
- Sending gRPC traffic to port 4318 or HTTP traffic to port 4317; the error messages are often unhelpful.
- Forgetting the
/v1/tracespath when setting a signal-specific HTTP endpoint. - Exporting directly from thousands of pods to a remote backend instead of using a Collector for batching, retries and sampling.
- Ignoring partial success responses, which hide rejected data in plain sight.
- Terminating TLS inconsistently, so some exporters use
http://and othershttps://against the same gateway.
How Obseria helps
Obseria accepts OTLP over gRPC and HTTP natively, so existing OpenTelemetry SDKs and Collectors can send data without proprietary agents; typically the first trace arrives within minutes of pointing the exporter at Obseria. Data can be exported again via OTLP at any time, which keeps you free to change tools. Learn more on the OpenTelemetry product page and in our guide to running the Collector in production.