OpenTelemetry Span Kinds

Last updated: May 21, 2026

The span kind describes the role of a span in a distributed trace.

It helps observability tools understand whether a span represents:

  • work happening inside a service,

  • an incoming request,

  • an outgoing request,

  • a message being produced,

  • or a message being consumed.

Choosing the right span kind makes traces easier to read and helps build accurate service maps, dependency graphs, and latency breakdowns.

Server

A server span represent the handling of a synchronous inbound request on a service. This means another service, browser, CLI, or external system called this service and is waiting for a response.

Common examples:

  • receiving an HTTP request,

  • handling a gRPC call,

  • processing an incoming RPC request.

A server span often has a corresponding client span on the caller side (if that caller service is instrumented with tracing).

Example

API receives GET /users/123

Span kind:

server
image.png

Client

A client span represents an outbound request to another service.

This usually means the current service is calling a remote system and waiting for a response.

Common examples:

  • making an HTTP request,

  • calling a gRPC service,

  • querying a database,

  • calling an external API.

A client span often has a corresponding server span on the receiving side (if that callee service is instrumented)

Example

API calls the user-service

Span kind:

client
image.png

Producer

A producer span represents sending or publishing a message to a broker, queue, topic, or stream.

This is used for asynchronous communication. The producer usually does not wait for the full processing of the message to finish.

Common examples:

  • publishing a Kafka message,

  • sending a message to RabbitMQ,

  • writing an event to a queue,

  • pushing a job to a background worker system.

Unlike client and server, producer and consumer spans do not usually represent a direct request/response latency relationship. The producer span may end long before the consumer starts processing the message.

Example

Checkout service publishes OrderCreated

Span kind:

producer
image.png

Consumer

A consumer span represents receiving or processing a message from a broker, queue, topic, or stream.

This is the other side of asynchronous communication.

Common examples:

  • consuming a Kafka message,

  • reading from RabbitMQ,

  • processing a queued job,

  • handling an event from a stream.

A consumer span is typically related to a previous producer span, but it may happen later and in a different trace shape than a normal synchronous request.

Example

Email service consumes OrderCreated and sends a confirmation email

Span kind:

consumer
image.png

Internal

An internal span represents an operation that does not cross a process boundary. The span represents work happening inside a service, without directly representing communication with another system.

This is the default span kind when no explicit kind is provided.

Common examples:

  • validating input,

  • rendering a template,

  • calculating a price,

  • running business logic,

  • reading from an in-memory cache,

  • executing an internal function.

Use internal for spans that help explain what happened inside a service, but are not themselves incoming requests, outgoing requests, produced messages, or consumed messages.

Example

Calculate cart total

Span kind:

internal
image.png