> ## Documentation Index
> Fetch the complete documentation index at: https://laminar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Metadata

Trace metadata applies to the entire trace. Use it for information that's constant across spans:

* **Environment** — production, staging, development
* **Region** — us-west, eu-central
* **Deployment** — version numbers, feature flags, A/B test variants
* **Request context** — correlation IDs, upstream service info

Set metadata early—ideally where the trace begins—so all spans share the same context.

## Adding Metadata

Set metadata inside an active span context (for example, inside `observe()` or an `@observe`d function). If you call it outside any span context, it won’t attach to anything.

<Tabs items={['TypeScript', 'Python']}>
  <Tab title="TypeScript">
    ```typescript theme={null}
    import { Laminar, observe } from '@lmnr-ai/lmnr';

    await observe({ name: 'processRequest' }, async () => {
      Laminar.setTraceMetadata({
        environment: 'production',
        featureFlag: 'new-algorithm-v2',
        region: 'us-west',
      });
    });
    ```

    See also: [`Laminar.setTraceMetadata`](/sdk/trace-methods#ts-laminar-set-trace-metadata) and [`observe(..., { metadata })`](/sdk/observe#ts-observe)
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    from lmnr import Laminar, observe

    @observe()
    def process_request():
        Laminar.set_trace_metadata({
            "environment": "production",
            "feature_flag": "new-algorithm-v2",
            "region": "us-west",
        })
    ```

    See also: [`Laminar.set_trace_metadata`](/sdk/trace-methods#py-laminar-set-trace-metadata) and [`@observe(metadata=...)`](/sdk/observe#py-observe)
  </Tab>
</Tabs>

## Notes

* Trace metadata is merged as spans arrive. If multiple spans set the same key, the **last span processed wins** (order is not guaranteed), so values can change while a trace is still ingesting.
* Set each metadata key in one place per trace (ideally the root span) and avoid duplicate keys in nested `observe(...)` calls or AI SDK telemetry.
* Keep metadata JSON-serializable and avoid sensitive data.

## Filtering by Metadata

In the Laminar UI, metadata filters currently match **exact key-value pairs** (for example, `region=us-west`).

<Note>
  If a trace seems to appear in results while it’s running and then disappears after it finishes, check whether
  the same metadata key is being set by multiple spans. Because metadata is merged on ingestion, the final value
  can change as more spans arrive, which can flip whether a trace matches a filter.
</Note>

## Metadata vs Tags

|          | Metadata                             | Tags                          |
| -------- | ------------------------------------ | ----------------------------- |
| Scope    | Entire trace                         | Individual spans              |
| Format   | Key-value pairs                      | String labels                 |
| Best for | Environment, cohort, request context | Categorization, review labels |

## Best Practices

* Use consistent keys (`environment`, `region`, `feature_flag`).
* Use `environment` for prod/staging/dev; add a low-cardinality key like `developer` or `source` to separate dev traces in a shared project.
* Keep it lightweight and JSON-serializable.
* Avoid sensitive data (no PII).
