Correlate backend AI behaviors (Langfuse LLM traces) directly to frontend user behaviors (PostHog Session Replay) to visually debug AI-driven UX errors, rage-clicks, and hallucination triggers.

đź§  The Core Concept

Goal: Jump from a problematic LLM generation (trace) in Langfuse straight to the user’s video recording in PostHog. Mechanism: The PostHog session_id is the golden thread. It must be generated on the frontend, passed to the backend, and attached to Langfuse traces as the sessionId.


⚡ Patterns (Do This)

1. Frontend: Auto-inject Session Headers

Configure posthog-js to automatically attach the active session ID to all requests destined for your backend API.

// frontend/app.js
posthog.init("<ph_project_token>", {
  api_host: "https://us.i.posthog.com",
  // Auto-injects `X-POSTHOG-SESSION-ID` & `X-POSTHOG-DISTINCT-ID`
  tracing_headers: ["api.your-app.com"],
})

2. Backend: Extract & Bind to Trace

Extract the PostHog headers on your backend and bind them directly to your Langfuse trace context.

// backend/api.ts
export async function handleLLMRequest(req: Request) {
  // 1. Extract the PostHog session ID
  const phSessionId = req.headers.get("x-posthog-session-id")
  const phDistinctId = req.headers.get("x-posthog-distinct-id")
 
  // 2. Bind to Langfuse Trace
  const trace = langfuse.trace({
    name: "Chat Completion",
    sessionId: phSessionId, // đź”— The Golden Thread!
    userId: phDistinctId, // Keep distinct_id aligned
    metadata: {
      source: "web_client",
    },
  })
 
  // ... execute LLM logic ...
}

3. Native Integration: Sync Langfuse to PostHog

To see the big picture (costs, latency vs retention), configure the official integration.

  • Langfuse UI: Go to Settings -> Integrations -> PostHog.
  • Input: PostHog Hostname & API Key.
  • Result: Langfuse continuously exports trace data, scores, and metrics into PostHog as custom events, linkable to the user’s timeline.

🛑 Anti-Patterns (Avoid This)

  • ❌ Mismatched Session IDs: Generating a fresh uuid() on the backend for the Langfuse sessionId. This completely breaks the link to PostHog’s session replay. You must consume PostHog’s session ID.
  • ❌ Assuming Magic Auto-Correlation: The Langfuse-PostHog integration exports metrics. It does not auto-magically link traces to session replays if you forget to pass the session_id between client and server.
  • ❌ Using userId instead of sessionId: userId (or PostHog’s distinct_id) links to the user, but a user can have hundreds of sessions. Finding the exact recording of the failure requires the sessionId.
  • ❌ CORS Blockage: Forgetting to expose or allow X-POSTHOG-SESSION-ID in your backend CORS configuration, causing frontend requests to be blocked.

🏆 Best Practices

  • Enable “AI Metrics” Dashboard: Once integrated, use PostHog’s pre-built “AI Metrics” dashboard to immediately visualize Langfuse data alongside product analytics.
  • Add URL Context: If possible, pass the current frontend URL into the Langfuse trace metadata.url. This gives immediate context in Langfuse before even clicking over to PostHog.
  • Handle Missing Headers Gracefully: Some users block trackers (AdBlockers blocking PostHog). If x-posthog-session-id is missing, fallback to a backend-generated UUID for Langfuse so you still get LLM observability, even without the replay link.
  • Send Feedback Scores: Use Langfuse feedback/scores (e.g., user clicked 👍/👎). These export to PostHog, allowing you to filter Session Replays purely for interactions where the user downvoted the AI response.