Skip to main content
Baggage is used to attach log messages or debugging information to the context. It allows you to propagate key-value pairs across service boundaries alongside trace context.

Overview

Baggage provides a way to carry user-defined metadata across process boundaries. Unlike trace context, which is used for correlation, baggage is designed to carry application-specific data that needs to be available throughout a distributed transaction. References:

Methods

get

def get(key: String): Option[Baggage.Entry]
Returns the entry to which the specified key is mapped, or None if this baggage contains no mapping for the key. Returns: Some(entry) if the key exists, None otherwise Example:
val entry = baggage.get("user-id")
entry.foreach(e => println(s"User ID: ${e.value}"))

updated (with metadata option)

def updated(key: String, value: String, metadata: Option[String]): Baggage
Adds or updates the entry that has the given key. Returns: A new Baggage instance with the updated entry

updated (with metadata)

def updated(key: String, value: String, metadata: String): Baggage
Adds or updates the entry that has the given key with the specified metadata. Returns: A new Baggage instance with the updated entry Example:
val updated = baggage.updated("request-id", "abc123", "sensitive")

updated (without metadata)

def updated(key: String, value: String): Baggage
Adds or updates the entry that has the given key without any metadata. Returns: A new Baggage instance with the updated entry Example:
val updated = baggage.updated("user-id", "user-123")

removed

def removed(key: String): Baggage
Removes the entry that has the given key if it is present. Returns: A new Baggage instance without the specified entry Example:
val updated = baggage.removed("temporary-flag")

size

def size: Int
Returns the number of entries in this baggage. Example:
println(s"Baggage contains ${baggage.size} entries")

isEmpty

def isEmpty: Boolean
Returns whether this baggage is empty, containing no entries. Example:
if (baggage.isEmpty) {
  println("No baggage entries")
}

asMap

def asMap: Map[String, Baggage.Entry]
Returns a map representation of this baggage. Returns: A Map containing all baggage entries keyed by their names Example:
baggage.asMap.foreach { case (key, entry) =>
  println(s"$key = ${entry.value}")
}

Factory Methods

empty

def empty: Baggage
Creates an empty Baggage instance with no entries. Example:
val baggage = Baggage.empty
  .updated("user-id", "123")
  .updated("request-id", "abc")

Nested Types

Baggage.Entry

Represents an entry that the Baggage holds associated with a key.

Properties

Factory Method

def apply(value: String, metadata: Option[Metadata]): Entry
Creates a new Entry with the specified value and optional metadata.

Baggage.Metadata

An opaque wrapper for a string that represents metadata for a baggage entry.

Properties

Factory Method

def apply(value: String): Metadata
Creates a new Metadata instance wrapping the given string value.

Type Class Instances

Hash

Baggage has a Hash instance from Cats, allowing for equality comparisons and hashing based on the baggage’s entries.

Show

Baggage has a Show instance that formats the baggage as:
Baggage{key1=value1,key2=value2;metadata}

Usage Examples

Creating and updating baggage

import org.typelevel.otel4s.baggage.Baggage

// Start with empty baggage
val baggage = Baggage.empty
  .updated("user-id", "user-123")
  .updated("tenant-id", "tenant-456")
  .updated("feature-flag", "enabled", "experimental")

println(baggage.size) // 3

Retrieving values

baggage.get("user-id") match {
  case Some(entry) => println(s"User ID: ${entry.value}")
  case None => println("User ID not found")
}

Removing entries

val updated = baggage.removed("feature-flag")
println(updated.size) // 2

Iterating over entries

baggage.asMap.foreach { case (key, entry) =>
  entry.metadata match {
    case Some(meta) => println(s"$key = ${entry.value} (${meta.value})")
    case None => println(s"$key = ${entry.value}")
  }
}

Working with metadata

import org.typelevel.otel4s.baggage.Baggage

val metadata = Baggage.Metadata("sensitive")
val entry = Baggage.Entry("secret-value", Some(metadata))

val baggage = Baggage.empty.updated("api-key", "key-123", "confidential")

baggage.get("api-key").foreach { entry =>
  println(s"Value: ${entry.value}")
  entry.metadata.foreach(m => println(s"Metadata: ${m.value}"))
}

Best Practices

  1. Keep baggage small: Baggage is propagated with every request, so keep the number and size of entries minimal
  2. Avoid sensitive data: Unless properly secured, baggage may be logged or exposed in headers
  3. Use metadata wisely: Metadata can indicate properties like whether data is sensitive or its purpose
  4. Immutability: All operations return new Baggage instances; the original is never modified

Build docs developers (and LLMs) love