GuidesOpenTelemetry

What is OTLP? The OpenTelemetry protocol explained

P
Praveen K B·September 10, 2026·13 min read

Learn what OTLP is, how it moves logs, metrics and traces, how HTTP and gRPC differ, and how to configure endpoints, ports and retries safely in production.

OpenTelemetry mascot carrying logs, metrics and traces between an application and observability backends using OTLP

An application is configured with OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf and sends telemetry to http://collector:4317. The Collector is listening. DNS works. The port is open. Nothing arrives.

The problem is one small mismatch: the application is sending OTLP over HTTP to the default OTLP/gRPC port. Both sides speak OTLP, but they are knocking on different doors.

That is the first useful thing to understand about OTLP. It is not a single URL or one wire format.

OTLP, short for OpenTelemetry Protocol, is the standard protocol OpenTelemetry uses to encode and transport telemetry between sources, Collectors and observability backends. It carries logs, metrics and traces over gRPC or HTTP while preserving the OpenTelemetry data model.

What is OTLP?

OTLP is a vendor-neutral telemetry delivery protocol defined by the OpenTelemetry project. An OpenTelemetry SDK, Collector or another compatible client can use it to send telemetry to any server that implements the same protocol.

The current OTLP specification defines three parts of that exchange:

  • encoding: how logs, metrics and traces are represented using Protocol Buffers
  • transport: how those messages travel over gRPC or HTTP
  • delivery: how a receiver reports success, rejection, throttling and retryable failure

OTLP is stable for logs, metrics and traces. The profiles signal remains under development, so do not treat every OTLP signal as having the same maturity.

The protocol gives telemetry a common path across languages and vendors. It does not decide which spans to sample, redact secrets, retain data or provide a query language. Those jobs belong to SDKs, Collectors and backends.

Where OTLP sits in an OpenTelemetry pipeline

OTLP connects components. It is not the component itself.

OpenTelemetry SDK --OTLP--> Collector --OTLP--> observability backend

The first hop is optional. An SDK can send OTLP directly to a compatible backend:

OpenTelemetry SDK --OTLP--> observability backend

OpenTelemetry mascot carrying telemetry from an application through a Collector to a backend using OTLP

An OTLP exporter is the sending side. It serializes OpenTelemetry data, attaches transport settings such as headers or compression and sends export requests to an endpoint.

An OTLP receiver is the listening side. It accepts those requests, decodes them and hands the telemetry to the next component. In the OpenTelemetry Collector, the otlp receiver can listen for OTLP/gRPC, OTLP/HTTP or both.

One Collector can therefore receive OTLP from an application and export OTLP to another Collector or backend. The protocol stays the same while the sender and receiver roles change at each hop.

If the Collector itself is new to you, start with the OpenTelemetry Collector guide. This article stays at the protocol boundary.

How OTLP works

OTLP uses a request-response model. A client sends an export request containing one signal and the server returns a response for that request.

Each request carries a hierarchy rather than repeating the same context on every record. A trace request, for example, groups spans by resource and instrumentation scope. Logs and metrics follow a similar structure.

resource -> instrumentation scope -> spans, metric points or log records

The resource identifies the entity producing telemetry, using attributes such as service.name, service.version and deployment environment. The instrumentation scope identifies the library that produced it. The records contain the signal-specific data.

This structure is one reason OpenTelemetry semantic conventions matter. OTLP can carry an attribute faithfully, but it cannot make two teams use the same name for the same idea.

OTLP uses Protocol Buffers

OTLP defines its messages with Protocol Buffers. Both transports use the same underlying message schema:

  • OTLP/gRPC sends binary Protobuf messages through gRPC service calls.
  • OTLP/HTTP can send binary Protobuf or JSON-encoded Protobuf in HTTP POST bodies.

JSON encoding is useful when an environment requires it or when a payload must be inspected with familiar HTTP tools. Binary Protobuf is the usual production choice because it is more compact.

A response is an acknowledgement, not permanent storage

A successful response means the receiving node accepted the request. It does not prove that the data survived every later hop or reached durable storage.

This distinction matters in a multi-hop pipeline:

application -> agent Collector -> gateway Collector -> backend

Each acknowledgement covers one client-server pair. Queues, retries and persistence between later nodes still need their own configuration and monitoring.

OTLP/HTTP vs OTLP/gRPC

OTLP has two standard transports. Neither is a less legitimate version of the protocol.

DetailOTLP/HTTPOTLP/gRPC
Default port43184317
PayloadBinary Protobuf or JSON-encoded ProtobufBinary Protobuf
Request styleHTTP POSTUnary gRPC export call
Signal path/v1/traces, /v1/metrics, /v1/logsSignal-specific gRPC service
Network fitFamiliar HTTP proxies, load balancers and debugging toolsEnvironments with working HTTP/2 and gRPC support
Typical protocol valuehttp/protobuf or http/jsongrpc

OpenTelemetry mascot choosing the matching OTLP gRPC and HTTP ports

The OpenTelemetry exporter specification recommends starting with OTLP/HTTP using binary Protobuf unless compatibility requires gRPC. Test gRPC when its connection model offers a measurable benefit in your environment.

Do not choose gRPC because a comparison page calls it the “fast option” and stop there. Actual throughput depends on exporter implementation, request concurrency, payload size, latency, compression and the receiver. Test both through the network path you will operate.

HTTP is often easier to inspect with existing proxies and tooling. gRPC avoids signal paths and is widely used between backend services and Collectors. Browser environments usually favor HTTP, subject to the receiver's CORS and authentication setup.

The choice must match on both ends. Sending HTTP to a gRPC-only listener does not become gRPC because the port number looks close enough.

OTLP ports, paths and endpoints

The defaults are simple:

  • OTLP/gRPC: 4317
  • OTLP/HTTP: 4318
  • traces over HTTP: /v1/traces
  • metrics over HTTP: /v1/metrics
  • logs over HTTP: /v1/logs

The paths are part of OTLP/HTTP, not OTLP/gRPC.

For an SDK exporter, the broad environment variables are:

export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318

When the general OTEL_EXPORTER_OTLP_ENDPOINT is used for OTLP/HTTP, compliant exporters construct the signal URLs from that base. Traces go to /v1/traces, metrics to /v1/metrics and logs to /v1/logs.

Signal-specific endpoint variables behave differently. Their URLs are used as provided, so include the complete path:

export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://otel-collector:4318/v1/traces
export OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://otel-collector:4318/v1/metrics
export OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=http://otel-collector:4318/v1/logs

That base-versus-complete-URL distinction produces a surprising number of 404 responses. The official OTLP exporter configuration defines the precedence and URL construction rules. Language SDK support still varies, so check the exporter documentation for the SDK version you deploy.

Ports 4317 and 4318 are defaults, not requirements. A hosted backend may expose OTLP over port 443 and a Collector can listen on another port. Configure the endpoint the receiver actually exposes.

Configure an OTLP receiver and exporter

The following Collector configuration accepts OTLP over both transports and sends the received traces to the debug exporter:

receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318
 
exporters:
  debug:
    verbosity: basic
 
service:
  pipelines:
    traces:
      receivers: [otlp]
      exporters: [debug]

The receiver block only defines the listeners. The pipeline activates the receiver for traces. If you need a complete three-signal example with processors and validation, use the OpenTelemetry Collector configuration guide.

To forward data to an OTLP/HTTP destination, replace or supplement debug with an HTTP exporter:

exporters:
  otlp_http/backend:
    endpoint: https://telemetry.example.com
    headers:
      Authorization: Bearer ${env:OTLP_TOKEN}
 
service:
  pipelines:
    traces:
      receivers: [otlp]
      exporters: [otlp_http/backend]

The receiver and exporter can use different transports. A Collector may receive gRPC from applications and export HTTP to the backend. It decodes the incoming request into its internal data model before the exporter encodes the outgoing request.

Should an SDK send OTLP directly or through a Collector?

Direct export is valid. A Collector is not a protocol tax that every small deployment must pay.

Send directly whenPut a Collector in the path when
one service sends to one OTLP backendmany services need one managed endpoint
the backend handles the required authenticationapplication code should not hold backend credentials
no shared processing is requiredtelemetry needs batching, filtering, redaction, enrichment or routing
a short local setup matters more than central policyqueues and retry behavior need to be operated centrally

Use a Collector when it has a specific job. “Our architecture diagram had an empty box” is not one.

For production pipelines, a Collector also keeps backend changes away from application configuration. The applications send OTLP to an internal endpoint; the Collector owns destination credentials and routing.

OTLP troubleshooting flow checking reachability, protocol, endpoint and exporter health

What happens when an OTLP request fails?

OTLP distinguishes full success, partial success and failure.

Full success

The server accepted the request. OTLP/HTTP returns 200 OK with an export response. OTLP/gRPC returns the corresponding successful service response.

Partial success

The server accepted some records and rejected others. Its response includes the rejected item count and may include an error message.

The client must not retry the whole request after a partial-success response. Doing so would resend the accepted records and could create duplicates. Instead, record the rejection and fix the data or receiver limit that caused it.

Retryable failure

Temporary failures may be retried. For OTLP/HTTP, the specification lists 429, 502, 503 and 504 as retryable. A client should honor Retry-After when supplied and otherwise use exponential backoff with jitter.

For OTLP/gRPC, UNAVAILABLE is the usual retryable signal. A receiver can include retry timing information.

Non-retryable failure

Bad data and incompatible requests should be dropped rather than retried forever. OTLP/HTTP uses 400 Bad Request for permanently invalid data. Repeating the same request only converts a data problem into a queue problem.

OTLP also has an unavoidable duplicate edge case. If a server accepts a request but the response is lost, the client cannot know whether retrying will duplicate data. Treat OTLP as robust hop-to-hop delivery, not exactly-once delivery.

Common OTLP errors and how to read them

Most first-day OTLP failures I have debugged were boundary mismatches.

SymptomLikely causeCheck
gRPC UNIMPLEMENTED or HTTP/2 protocol errorTransport sent to the wrong listenerMatch grpc with the gRPC endpoint and http/protobuf with the HTTP endpoint
HTTP 404Missing or duplicated signal pathCheck whether the variable expects a base URL or complete /v1/... URL
HTTP 415Unsupported Content-Type or encodingUse application/x-protobuf for binary Protobuf or a receiver-supported JSON encoding
HTTP 401 or 403Missing or invalid authenticationCheck exporter headers and secret expansion
TLS handshake failureScheme, certificate or server name mismatchVerify http versus https, CA trust and endpoint hostname
HTTP 413 or gRPC resource exhaustionRequest exceeds a receiver limitReduce batch size or raise a tested receiver limit
Telemetry reaches the Collector but not the backendExporter, queue or downstream failureInspect Collector exporter logs and internal metrics

When debugging, prove one boundary at a time:

  1. Confirm the receiver is listening on the expected interface and port.
  2. Confirm exporter protocol and endpoint agree.
  3. Send one signal to the Collector's debug exporter.
  4. Add authentication and the remote backend only after that local path works.
  5. Watch rejected, failed and dropped telemetry counters rather than relying on an empty dashboard.

The Collector metrics guide covers the internal signals that show whether a receiver accepted data and whether an exporter sent it.

Send OTLP data to Parseable

Parseable accepts OTLP logs, metrics and traces over HTTP at /v1/logs, /v1/metrics and /v1/traces. A Collector can route each signal with the dataset headers Parseable expects.

This trace exporter uses the Parseable base URL; the OTLP HTTP exporter appends /v1/traces:

exporters:
  otlp_http/parseable_traces:
    endpoint: ${env:PARSEABLE_URL}
    encoding: proto
    headers:
      X-API-Key: ${env:PARSEABLE_API_KEY}
      X-P-Stream: otel-traces
      X-P-Log-Source: otel-traces
 
service:
  pipelines:
    traces:
      receivers: [otlp]
      exporters: [otlp_http/parseable_traces]

Use separate exporter instances when signals need different datasets or headers. The current Parseable OpenTelemetry documentation covers direct OTLP ingestion and signal-specific examples.

What OTLP does not do

OTLP is easy to give too much credit because it sits on an important boundary.

It does not:

  • instrument application code
  • define all attribute names and values
  • choose a sampling policy
  • redact sensitive data
  • guarantee durable end-to-end storage
  • provide search, dashboards or alerts
  • make a backend OpenTelemetry-native by itself

An endpoint accepting OTLP proves protocol compatibility. It does not prove that the backend preserves semantic conventions, correlates signals or lets you export the data without translating it into a private schema.

The practical rule

OTLP standardizes the handoff. To make that handoff work, match four things on both sides: transport, endpoint, signal and authentication.

Start with one signal and a local receiver. Prove it with the debug exporter. Then add the backend, processing and production failure behavior. That order removes several moving parts from the first error message—and usually finds the wrong door quickly.

Frequently Asked Questions

Share

Subscribe to our newsletter

Get the latest updates on Parseable features, best practices, and observability insights delivered to your inbox.

SFO

Parseable Inc.

584 Castro St, #2112

San Francisco, California

94114-2512

Phone: +1 (650) 444 6216

BLR

Cloudnatively Services Pvt Ltd.

JBR Tech Park

Whitefield, Bengaluru

560066

Phone: +91 9480931554

All systems operational

Parseable