Trace-First Context Management: Langfuse v4+ transitions to an observation-centric model prioritizing context managers over trace-specific imperative updates. This ensures correlating attributes (
user_id,session_id) universally apply to all downstream spans without complex joins.
π Quick Start: Context Propagation
Use propagate_attributes() as a context manager nested inside the @observe() decorator. Do not use it as a standalone decorator.
from langfuse.decorators import observe
from langfuse import propagate_attributes
@observe()
def run_pipeline(user_query):
# Apply global tracking attributes to all child observations
with propagate_attributes(
user_id="user_987",
session_id="session_xyz",
metadata={"source": "api", "region": "eu-central"},
tags=["prod", "v2-pipeline"]
):
return execute_llm_chain(user_query) # Inherits all attributes automaticallyπ‘ Best Practices: Patterns & Strategy
- Hybrid Instrumentation: Use
@observe()to define high-level workflow boundaries (RAG logic, agents). Let native integrations (Langchain, OpenAI) handle low-level LLM spans. - Embrace Default Filters: Langfuse v4+ uses smart
default span filtersto block non-GenAI infrastructure noise (HTTP requests, DB). Rely on these defaults out-of-the-box before building custom filters. - Observation-Centric Enrichment: Use
propagate_attributes()instead of old trace-specific update methods to enrich telemetry. This pushes attributes down to every observation, making single-table queries extremely efficient.
π¨ Gotchas / Anti-Patterns
- βExport Everythingβ Bloat: Reverting to pre-v4 behavior (exporting all non-blocked spans) massively increases noise and cost. Do not disable span filtering unless actively debugging.
- Orphaning Child Spans: Filtering out a parent span but keeping its children creates orphaned observations. This fundamentally breaks trace tree visualization in the Langfuse UI.
- Heavy Manual Nesting: Avoid imperative, verbose span generation logic inside business flows. Drop down to manual spans only when specific precision or standalone metadata is strictly required.
- Context Scope Leaks:
propagate_attributes()scopes exactly to itswithblock. Observations fired outside this block drop the context correlation completely.
π§ Configuration: Custom Hardening & Filters
Compose custom rules safely by augmenting the default filters, rather than overwriting them entirely. Use mask_otel_spans at the export stage to sanitize PII.
from langfuse import Langfuse
from langfuse.span_filter import is_default_export_span
# 1. Expand span capture safely
langfuse = Langfuse(
should_export_span=lambda span: is_default_export_span(span) or
span.instrumentation_scope_name == "custom-db-layer"
)
# 2. Debug span drops (check logs for 'dropped-span')
# export LANGFUSE_DEBUG="True"π Research / References
- Docs: Langfuse Tracing Overview
- Topic: Context Managers vs Decorators,
propagate_attributes, OpenTelemetry smart defaults.