diff --git a/content/docs/observability/features/environments.mdx b/content/docs/observability/features/environments.mdx
index b7fe4d48d7..a6d33b2f91 100644
--- a/content/docs/observability/features/environments.mdx
+++ b/content/docs/observability/features/environments.mdx
@@ -16,6 +16,8 @@ You can configure the environment by setting the `LANGFUSE_TRACING_ENVIRONMENT`
If both are specified, the initialization parameter takes precedence.
If nothing is specified, the default environment is `default`.
+In the Python SDK, you can also set the environment for a specific trace scope with `propagate_attributes(environment="...")`. This is useful when the environment belongs to the incoming request rather than to the service process itself, for example when one shared LLM proxy handles requests from development, staging, QA, and production. Use `as_baggage=True` to propagate that environment across service boundaries.
+
## Data Model
The `environment` attribute is available on all events in Langfuse:
@@ -40,7 +42,7 @@ This means:
```python
-from langfuse import get_client, observe
+from langfuse import get_client, observe, propagate_attributes
import os
# Set the environment variable
@@ -60,6 +62,13 @@ def main():
return "Hello"
main()
+
+# For request-scoped environments, propagate the environment explicitly.
+# This maps to the first-class langfuse.environment field.
+with langfuse.start_as_current_observation(as_type="span", name="proxy-request"):
+ with propagate_attributes(environment="staging"):
+ # All child observations created here are associated with staging.
+ pass
```
diff --git a/content/docs/observability/sdk/instrumentation.mdx b/content/docs/observability/sdk/instrumentation.mdx
index 781998f90c..6755ed63cb 100644
--- a/content/docs/observability/sdk/instrumentation.mdx
+++ b/content/docs/observability/sdk/instrumentation.mdx
@@ -458,6 +458,7 @@ You can add attributes to observations to help you better understand your applic
- [`metadata`](/docs/observability/features/metadata)
- [`version`](/docs/observability/features/releases-and-versioning)
- [`tags`](/docs/observability/features/tags)
+- [`environment`](/docs/observability/features/environments) (Python SDK)
- `traceName` (trace name)
To update the input and output of the trace, see [trace-level inputs/outputs](#trace-inputoutput-behavior).
@@ -466,6 +467,7 @@ To update the input and output of the trace, see [trace-level inputs/outputs](#t
Use [`propagate_attributes()`](https://python.reference.langfuse.com/langfuse#propagate_attributes) to add attributes to observations.
+In the Python SDK, `environment` is a first-class Langfuse environment and maps to `langfuse.environment`, not to trace metadata. Use it when the environment is request-scoped, for example when one shared proxy handles requests from multiple deployment environments.
```python /propagate_attributes/
from langfuse import get_client, propagate_attributes
@@ -478,6 +480,7 @@ with langfuse.start_as_current_observation(as_type="span", name="user-workflow")
session_id="session_abc",
metadata={"experiment": "variant_a"},
version="1.0",
+ environment="staging",
trace_name="user-workflow",
):
with langfuse.start_as_current_observation(as_type="generation", name="llm-call"):
@@ -541,6 +544,8 @@ await startActiveObservation("user-workflow", async () => {
For distributed tracing across multiple services, use the `as_baggage` parameter (see [OpenTelemetry documentation for more details](https://opentelemetry.io/docs/concepts/signals/baggage/)) to propagate attributes via HTTP headers.
+In the Python SDK, `environment` can also be propagated this way. The environment is sent as `langfuse_environment` baggage and takes precedence over the downstream service's local `LANGFUSE_TRACING_ENVIRONMENT` or client-level environment for spans created within the propagated context.
+
@@ -554,6 +559,7 @@ with langfuse.start_as_current_observation(as_type="span", name="api-request"):
with propagate_attributes(
user_id="user_123",
session_id="session_abc",
+ environment="staging",
as_baggage=True,
):
requests.get("https://service-b.example.com/api")
diff --git a/content/docs/observability/sdk/overview.mdx b/content/docs/observability/sdk/overview.mdx
index 3d542aa1b4..43f4956068 100644
--- a/content/docs/observability/sdk/overview.mdx
+++ b/content/docs/observability/sdk/overview.mdx
@@ -356,7 +356,7 @@ graph TD
- **Langfuse Event**: A Langfuse-event tracks a point in time action.
- [**Other observation types**](/docs/observability/features/observation-types): Langfuse supports other observation types such as tool calls, RAG retrieval steps, etc.
- **Context Propagation**: OpenTelemetry automatically handles the propagation of the current trace and span context. This means when you call another function (whether it's also traced by Langfuse, an OTel-instrumented library, or a manually created span), the new span will automatically become a child of the currently active span, forming a correct trace hierarchy.
-- [**Attribute Propagation**](/docs/observability/sdk/instrumentation#add-attributes-to-observations): Certain trace attributes (`user_id`, `session_id`, `metadata`, `version`, `tags`) can be automatically propagated to all child observations using `propagate_attributes()`. This ensures consistent attribute coverage across all observations in a trace. See the [instrumentation docs](/docs/observability/sdk/python/instrumentation#propagating-trace-attributes) for details.
+- [**Attribute Propagation**](/docs/observability/sdk/instrumentation#add-attributes-to-observations): Certain trace attributes (`user_id`, `session_id`, `metadata`, `version`, `tags`, and request-scoped `environment` in the Python SDK) can be automatically propagated to all child observations using `propagate_attributes()`. This ensures consistent attribute coverage across all observations in a trace. See the [instrumentation docs](/docs/observability/sdk/python/instrumentation#propagating-trace-attributes) for details.
The Langfuse SDKs provide wrappers around OTel spans ([`LangfuseSpan`](https://python.reference.langfuse.com/langfuse#LangfuseSpan), [`LangfuseGeneration`](https://python.reference.langfuse.com/langfuse#LangfuseGeneration)) that offer convenient methods for interacting with Langfuse-specific features like scoring and media handling, while still being native OTel spans under the hood. You can also use these wrapper objects to add Langfuse trace attributes via [`update_trace()`](https://python.reference.langfuse.com/langfuse#LangfuseEvent.update) or use [`propagate_attributes()`](https://python.reference.langfuse.com/langfuse#propagate_attributes) for automatic propagation to all child observations.
diff --git a/content/docs/observability/sdk/upgrade-path/python-v3-to-v4.mdx b/content/docs/observability/sdk/upgrade-path/python-v3-to-v4.mdx
index b868f4b6ca..51248cc53a 100644
--- a/content/docs/observability/sdk/upgrade-path/python-v3-to-v4.mdx
+++ b/content/docs/observability/sdk/upgrade-path/python-v3-to-v4.mdx
@@ -90,7 +90,7 @@ Filtering can break trace trees when intermediate or parent spans are dropped wh
### `update_current_trace()` decomposed into 3 methods
-In the new model, correlating attributes (`user_id`, `session_id`, `metadata`, `tags`) must live on every observation, not just the trace. This is why they move to `propagate_attributes()` — a context manager that automatically applies these attributes to the current and all child observations created within its scope.
+In the new model, correlating attributes (`user_id`, `session_id`, `metadata`, `tags`, and request-scoped `environment`) must live on every observation, not just the trace. This is why they move to `propagate_attributes()` — a context manager that automatically applies these attributes to the current and all child observations created within its scope.
**v3:**
@@ -125,6 +125,7 @@ def my_function():
version="1.0",
metadata={"key": "value"},
tags=["tag1"],
+ environment="staging",
):
result = call_llm("hello")
@@ -137,15 +138,15 @@ def my_function():
**Key differences:**
-| Attribute | v3 | v4 |
-| ------------------------------------------ | --------------------------------------- | ---------------------------------------------------- |
-| `name` | `update_current_trace(name=...)` | `propagate_attributes(trace_name=...)` |
-| `user_id`, `session_id`, `tags`, `version` | `update_current_trace(...)` | `propagate_attributes(...)` |
-| `metadata` | `update_current_trace(metadata=any)` | `propagate_attributes(metadata=dict[str,str])` |
-| `input`, `output` | `update_current_trace(...)` | `set_current_trace_io(...)` (deprecated) |
-| `public` | `update_current_trace(public=True)` | `set_current_trace_as_public()` |
-| `release` | `update_current_trace(release=...)` | Removed — use `LANGFUSE_RELEASE` env var |
-| `environment` | `update_current_trace(environment=...)` | Removed — use `LANGFUSE_TRACING_ENVIRONMENT` env var |
+| Attribute | v3 | v4 |
+| ------------------------------------------ | --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `name` | `update_current_trace(name=...)` | `propagate_attributes(trace_name=...)` |
+| `user_id`, `session_id`, `tags`, `version` | `update_current_trace(...)` | `propagate_attributes(...)` |
+| `metadata` | `update_current_trace(metadata=any)` | `propagate_attributes(metadata=dict[str,str])` |
+| `input`, `output` | `update_current_trace(...)` | `set_current_trace_io(...)` (deprecated) |
+| `public` | `update_current_trace(public=True)` | `set_current_trace_as_public()` |
+| `release` | `update_current_trace(release=...)` | Removed — use `LANGFUSE_RELEASE` env var |
+| `environment` | `update_current_trace(environment=...)` | Use `LANGFUSE_TRACING_ENVIRONMENT` or `Langfuse(environment=...)` for process-level environments. Use `propagate_attributes(environment=...)` for request-scoped environments. |
`set_current_trace_io()` is deprecated and exists only for backward
diff --git a/content/docs/v4.mdx b/content/docs/v4.mdx
index b207be9403..f1e3710773 100644
--- a/content/docs/v4.mdx
+++ b/content/docs/v4.mdx
@@ -89,7 +89,7 @@ To take advantage of the new data model and explore your data in real time, use
- **JS/TS SDK:** v5 ([migration guide](/docs/observability/sdk/upgrade-path/js-v4-to-v5))
- **Direct OpenTelemetry ingestion:** set `x-langfuse-ingestion-version: 4` on your OTEL span exporter ([OpenTelemetry setup](/integrations/native/opentelemetry))
-For SDK users, the key change is that `update_current_trace()` and `updateActiveTrace()` are replaced by `propagate_attributes()`, which automatically pushes attributes like `user_id`, `session_id`, `metadata`, and `tags` to all child observations.
+For SDK users, the key change is that `update_current_trace()` and `updateActiveTrace()` are replaced by `propagate_attributes()`, which automatically pushes attributes like `user_id`, `session_id`, `metadata`, `tags`, and request-scoped `environment` in the Python SDK to all child observations.
### Optional: Migrate LLM-as-a-judge evaluations
diff --git a/content/faq/all/managing-different-environments.mdx b/content/faq/all/managing-different-environments.mdx
index 1430303186..d91a570126 100644
--- a/content/faq/all/managing-different-environments.mdx
+++ b/content/faq/all/managing-different-environments.mdx
@@ -16,9 +16,10 @@ Use **separate projects** if you need different access controls per environment,
## Environments (Recommended)
-The recommended approach for managing different environments in Langfuse is to use the built-in [Environments](/docs/tracing-features/environments) feature. This allows you to organize your traces, observations, and scores from different contexts such as production, staging, or development within the same project.
+The recommended approach for managing different environments in Langfuse is to use the built-in [Environments](/docs/observability/features/environments) feature. This allows you to organize your traces, observations, and scores from different contexts such as production, staging, or development within the same project.
You can configure the environment by setting the `LANGFUSE_TRACING_ENVIRONMENT` environment variable or by using the `environment` parameter in the client initialization.
+In the Python SDK, use `propagate_attributes(environment="...", as_baggage=True)` when a shared service, such as an LLM proxy, should inherit the caller's environment per request.
## Separate Projects