Skip to content

Baggage

In OpenTelemetry, Baggage is a key-value store that can be used to propagate any data you like alongside context during (distributed) tracing. Baggage is included in the context of a trace, and is propagated across service boundaries, allowing you to attach metadata to a trace that can be accessed by any service that participates in that trace.

Technically, Baggage is a separate key-value store and is formally unassociated with attributes on spans, metrics, or logs without explicitly creating those attributes from the Baggage.

However, a common use cases for Baggage is to add data to span attributes across a whole trace. Because of this, Logfire provides convenience APIs for setting Baggage and automatically adding Baggage to descendant span attributes.

Why use Baggage to set attributes?

Though tracing makes it a lot easier to understand and visualize the relationship between parent and child spans, it's still usually easiest to express filtering criteria on an individual span when doing custom searches, aggregations, etc.

As a concrete example, you might have received an issue report from a user with user_id scolvin, and want to search for all spans corresponding to slow database queries that happened in requests made by that user. You might find all slow database requests with the query duration > 1 AND attributes ? 'db.statement', but trying to filter down to only those spans coming from requests by a specific user is harder.

Basic usage

Here's how to solve the above example using Baggage:

import logfire

logfire.configure()

with logfire.set_baggage(user_id='scolvin'):
    print(logfire.get_baggage())  # (just for demonstration, not usually needed)
    #> {'user_id': 'scolvin'}

    # All spans opened here (and their descendants)
    # will have the attribute `user_id` set to 'scolvin'
    # (or more attributes if you set other baggage values)
    with logfire.span('inside-baggage-span'):
        ...

Then you can update your query to duration > 1 AND attributes ? 'db.statement' AND attributes->>'user_id' = 'scolvin'.

Disabling

If you don't want to add Baggage to span attributes, pass add_baggage_to_attributes=False to the logfire.configure() function. This may slightly improve performance. The set_baggage contextmanager will still update the OpenTelemetry Baggage and propagate it to other services.

Baggage values requirements

While baggage can technically contain any data type, only strings will be set as attributes on spans. Additionally, strings longer than 1000 characters will be truncated with a warning, in both logfire.set_baggage and the span attributes.

Using with multiple services

Baggage is propagated automatically to other processes along with the trace context if you've instrumented the appropriate libraries, e.g. HTTP clients and servers. See the Distributed Tracing documentation for more information on how this works.

For example, if you:

  1. Instrument httpx in one service, where you
  2. make an httpx request in the context of with logfire.set_baggage
  3. to another service that has instrumented fastapi

then the values set in logfire.set_baggage in step 2 will be available as Baggage in the fastapi service, and by default those values will be added as attributes to the spans created in that service.

This works by including the values in the Baggage HTTP header in the request made by httpx. This happens regardless of whether the request is received by a server that can read the Baggage or not, or whether either service sets Baggage as span attributes. So it's important to be careful about what you put in Baggage:

  • Don't put sensitive information in Baggage, as it may be sent to third party services. While span attributes from baggage are still scrubbed by default, the Baggage header itself is not scrubbed.
  • Don't put large values in Baggage, as this may add bloat to HTTP headers. Large values may also be dropped by servers instead of being propagated. This is one reason why Logfire truncates Baggage values longer than 1000 characters.

With other OpenTelemetry SDKs

If all your services are using the Python Logfire SDK, then Baggage will be set as span attributes automatically by default, so you only need to ensure that context propagation is working.

For other OpenTelemetry SDKs, Baggage will still be propagated automatically, but to set the span attributes requires extra configuration. Try searching for BaggageSpanProcessor and the name of the language you're using.