Complete Langfuse integration skill pack with 24 skills covering LLM observability, tracing, prompt management, and evaluation. Flagship tier vendor pack.
Installation
Open Claude Code and run this command:
/plugin install langfuse-pack@claude-code-plugins-plus
Use --global to install for all projects, or --project for current project only.
Skills (24)
Configure Langfuse CI/CD integration with GitHub Actions and automated testing.
Langfuse CI Integration
Overview
Integrate Langfuse into CI/CD pipelines: trace validation tests, prompt regression testing, experiment-driven quality gates, automated prompt deployment from version control, and score monitoring.
Prerequisites
- Langfuse API keys stored as GitHub secrets (
LANGFUSEPUBLICKEY,LANGFUSESECRETKEY) - Test framework (Vitest or Jest)
- OpenAI API key for LLM tests
Instructions
Step 1: GitHub Actions Workflow for AI Quality Tests
# .github/workflows/langfuse-tests.yml
name: AI Quality Tests
on:
pull_request:
paths: ["src/ai/**", "src/prompts/**", "tests/ai/**"]
jobs:
ai-quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: "20", cache: "npm" }
- run: npm ci
- name: Run AI quality tests with tracing
env:
LANGFUSE_PUBLIC_KEY: ${{ secrets.LANGFUSE_PUBLIC_KEY }}
LANGFUSE_SECRET_KEY: ${{ secrets.LANGFUSE_SECRET_KEY }}
LANGFUSE_BASE_URL: ${{ vars.LANGFUSE_BASE_URL || 'https://cloud.langfuse.com' }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: npx vitest run tests/ai/ --reporter=verbose
- name: Langfuse connectivity check
env:
LANGFUSE_PUBLIC_KEY: ${{ secrets.LANGFUSE_PUBLIC_KEY }}
LANGFUSE_SECRET_KEY: ${{ secrets.LANGFUSE_SECRET_KEY }}
run: |
node -e "
const { LangfuseClient } = require('@langfuse/client');
const lf = new LangfuseClient();
lf.prompt.get('__ci-health__').catch(() => {});
console.log('Langfuse SDK initialized OK');
"
Step 2: Prompt Regression Tests
// tests/ai/prompt-quality.test.ts
import { describe, it, expect, afterAll } from "vitest";
import { LangfuseClient } from "@langfuse/client";
import { startActiveObservation, updateActiveObservation } from "@langfuse/tracing";
import OpenAI from "openai";
const langfuse = new LangfuseClient();
const openai = new OpenAI();
describe("Prompt Quality Regression", () => {
it("summarization prompt produces valid output", async () => {
const prompt = await langfuse.prompt.get("summarize-article", { type: "text" });
const compiled = prompt.compile({ maxLength: "100 words" });
const result = await startActiveObservation(
{ name: "ci-test-summarize", asType: "generation" },
async () => {
updateActiveObservation({ model: "gpt-4o-mini", input: compiled });
const response = await openai.chat.completions.create({
Diagnose and fix common Langfuse errors and exceptions.
Langfuse Common Errors
Overview
Diagnostic reference for the 10 most common Langfuse integration errors, with real error messages, root causes, and tested solutions.
Prerequisites
- Langfuse SDK installed
- API credentials configured
- Access to application logs or console output
Error Reference
1. Authentication Failed (401)
Error:
Langfuse: Unauthorized - Invalid API key
Error: 401 Unauthorized
Cause: API key missing, expired, revoked, or keys from wrong project.
Fix:
set -euo pipefail
# Verify env vars are set
echo "Public: ${LANGFUSE_PUBLIC_KEY:0:15}..."
echo "Secret: ${LANGFUSE_SECRET_KEY:0:10}..."
# Test auth against API
HOST="${LANGFUSE_BASE_URL:-https://cloud.langfuse.com}"
curl -s -o /dev/null -w "HTTP %{http_code}" \
"$HOST/api/public/health"
# Auth test
curl -s -o /dev/null -w "HTTP %{http_code}" \
-H "Authorization: Basic $(echo -n "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" | base64)" \
"$HOST/api/public/traces?limit=1"
2. Traces Not Appearing in Dashboard
Symptom: Code runs without errors but no traces show in UI.
Root causes (in order of likelihood):
- Data not flushed before process exits
- Wrong project keys (traces going to different project)
- Dashboard filter hiding traces
Fix:
// v4+: Ensure OTel SDK is shut down properly
const sdk = new NodeSDK({ spanProcessors: [new LangfuseSpanProcessor()] });
sdk.start();
// ... your code ...
await sdk.shutdown(); // MUST call this before process exits
// v3: Always flush
await langfuse.flushAsync();
// v3: Register shutdown handler for long-running processes
process.on("beforeExit", async () => {
await langfuse.shutdownAsync();
});
3. Network / Connection Errors
Error:
FetchError: request to https://cloud.langfuse.com failed
ECONNREFUSED / ETIMEDOUT
Fix:
set -euo pipefail
# Test connectivity
curl -v https://cloud.langfuse.com/api/public/health
# Check DNS
nslookup cloud.langfuse.com
# For self-hosted
curl -v $LANGFUSE_BASE_URL/api/public/health
// Increase timeout for slow networks
// v4+: Configure via OTel span processor options
// v3:
const langfuse = new Langfuse({ requestTimeout: 30000 });
4. Missing Token Usage
Symptom: Generations appear but token counts show zero.
Fix:
// For OpenAI streaming -- enable usage reporting
constExecute Langfuse primary workflow: Tracing LLM calls and spans.
Langfuse Core Workflow A: Tracing LLM Calls
Overview
End-to-end tracing of LLM calls, chains, and agents. Covers the OpenAI drop-in wrapper, manual tracing with startActiveObservation, RAG pipeline instrumentation, streaming response tracking, and LangChain integration.
Prerequisites
- Completed
langfuse-install-authsetup - OpenAI SDK installed (
npm install openai) - For v4+:
@langfuse/openai,@langfuse/tracing,@langfuse/otel,@opentelemetry/sdk-node
Instructions
Step 1: OpenAI Drop-In Wrapper (Zero-Code Tracing)
import OpenAI from "openai";
import { observeOpenAI } from "@langfuse/openai";
// Wrap the OpenAI client -- all calls are now traced automatically
const openai = observeOpenAI(new OpenAI());
// Every call captures: model, input, output, tokens, latency, cost
const response = await openai.chat.completions.create({
model: "gpt-4o",
messages: [
{ role: "system", content: "You are a helpful assistant." },
{ role: "user", content: "What is Langfuse?" },
],
});
// Add metadata to traces
const res = await observeOpenAI(new OpenAI(), {
generationName: "product-description",
generationMetadata: { feature: "onboarding" },
sessionId: "session-abc",
userId: "user-123",
tags: ["production", "onboarding"],
}).chat.completions.create({
model: "gpt-4o-mini",
messages: [{ role: "user", content: "Describe this product" }],
});
Step 2: Manual Tracing -- RAG Pipeline (v4+ SDK)
import { startActiveObservation, updateActiveObservation } from "@langfuse/tracing";
async function ragPipeline(query: string) {
return await startActiveObservation("rag-pipeline", async () => {
updateActiveObservation({ input: { query }, metadata: { pipeline: "rag-v2" } });
// Span: Query embedding
const embedding = await startActiveObservation("embed-query", async () => {
updateActiveObservation({ input: { text: query } });
const vector = await embedText(query);
updateActiveObservation({
output: { dimensions: vector.length },
metadata: { model: "text-embedding-3-small" },
});
return vector;
});
// Span: Vector search
const documents = await startActiveObservation("vector-search", async () => {
updateActiveObservation({ input: { dimensions: embedding.length } });
const docs = await searchVectorDB(embedding);
updateActiveObservation({
output: { documentCount: docs.length, topScore: docs[0]?.score },
});
return docs;
});
// Generation: LLM call wExecute Langfuse secondary workflow: Evaluation, scoring, and datasets.
Langfuse Core Workflow B: Evaluation, Scoring & Datasets
Overview
Implement LLM output evaluation using Langfuse scores (numeric, categorical, boolean), the experiment runner SDK for dataset-driven benchmarks, prompt management with versioned prompts, and LLM-as-a-Judge evaluation patterns.
Prerequisites
- Langfuse SDK configured with API keys
- Traces already being collected (see
langfuse-core-workflow-a) - For v4+:
@langfuse/clientinstalled
Instructions
Step 1: Score Traces via SDK
Langfuse supports three score data types: Numeric, Categorical, and Boolean.
import { LangfuseClient } from "@langfuse/client";
const langfuse = new LangfuseClient();
// Numeric score (e.g., 0-1 quality rating)
await langfuse.score.create({
traceId: "trace-abc-123",
name: "relevance",
value: 0.92,
dataType: "NUMERIC",
comment: "Highly relevant answer with good context usage",
});
// Categorical score (e.g., pass/fail classification)
await langfuse.score.create({
traceId: "trace-abc-123",
observationId: "gen-xyz-456", // Optional: score a specific generation
name: "quality-tier",
value: "excellent",
dataType: "CATEGORICAL",
});
// Boolean score (e.g., thumbs up/down)
await langfuse.score.create({
traceId: "trace-abc-123",
name: "user-approved",
value: 1, // 1 = true, 0 = false
dataType: "BOOLEAN",
comment: "User clicked thumbs up",
});
Step 2: User Feedback Collection
// API endpoint for frontend feedback widget
app.post("/api/feedback", async (req, res) => {
const { traceId, rating, comment } = req.body;
// Thumbs up/down
await langfuse.score.create({
traceId,
name: "user-feedback",
value: rating === "positive" ? 1 : 0,
dataType: "BOOLEAN",
comment,
});
// Granular star rating (1-5)
if (req.body.stars) {
await langfuse.score.create({
traceId,
name: "star-rating",
value: req.body.stars,
dataType: "NUMERIC",
comment: `${req.body.stars}/5 stars`,
});
}
res.json({ success: true });
});
Step 3: Prompt Management
// Fetch a versioned prompt from Langfuse
const textPrompt = await langfuse.prompt.get("summarize-article", {
type: "text",
label: "production", // or "latest", "staging"
});
// Compile with variables -- replaces {{variable}} placeholders
const compiled = textPrompt.compile({
maxLength: "100 words",
tone: "professional",
});
// Chat prompts return message arrays
cMonitor and optimize LLM costs using Langfuse analytics and dashboards.
Langfuse Cost Tuning
Overview
Track, analyze, and optimize LLM costs using Langfuse's built-in token/cost tracking, the Metrics API for programmatic cost analysis, model routing for cost reduction, and automated budget alerts.
Prerequisites
- Langfuse tracing with token usage captured (via
observeOpenAIor manualusagefields) - For Metrics API:
@langfuse/clientinstalled - Understanding of LLM pricing models
How Langfuse Tracks Costs
Langfuse automatically calculates costs for supported models (OpenAI, Anthropic, Google) when token usage is captured. For custom models, you can configure pricing in the Langfuse UI under Settings > Model Definitions.
Cost tracking works on observations of type generation and embedding. The observeOpenAI wrapper captures usage automatically; for manual tracing, include usage in your observation updates.
Instructions
Step 1: Ensure Token Usage is Captured
// Automatic: observeOpenAI captures everything
import { observeOpenAI } from "@langfuse/openai";
const openai = observeOpenAI(new OpenAI());
// Tokens, model, latency, and cost are all auto-tracked
// Manual: include usage in generation observations
import { startActiveObservation, updateActiveObservation } from "@langfuse/tracing";
await startActiveObservation(
{ name: "llm-call", asType: "generation" },
async () => {
updateActiveObservation({ model: "gpt-4o" }); // Model required for cost calc
const response = await openai.chat.completions.create({
model: "gpt-4o",
messages: [{ role: "user", content: prompt }],
});
updateActiveObservation({
output: response.choices[0].message.content,
usage: {
promptTokens: response.usage?.prompt_tokens,
completionTokens: response.usage?.completion_tokens,
totalTokens: response.usage?.total_tokens,
},
// Optional: override inferred cost (in USD)
// costInUsd: 0.0015,
});
}
);
Step 2: Query Costs via Metrics API
import { LangfuseClient } from "@langfuse/client";
const langfuse = new LangfuseClient();
// Fetch aggregated cost metrics
async function getCostReport(days: number) {
const fromTimestamp = new Date(Date.now() - days * 86400000).toISOString();
// Use the API to list traces with cost data
const traces = await langfuse.api.traces.list({
fromTimestamp,
limit: 1000,
orderBy: "timestamp",
});
const costByModel = new Map<string, { cost: number; tokens: number; count: number }>();
for (const trace of traces.data) {
const observations = await langfuse.api.observations.list({
traceId: trace.Manage Langfuse data export, retention, and compliance requirements.
Langfuse Data Handling
Overview
Manage the Langfuse data lifecycle: export traces and scores via the API, configure retention policies, handle GDPR data subject requests, anonymize data for analytics, and maintain audit trails.
Prerequisites
@langfuse/clientinstalled- Langfuse API keys with appropriate permissions
- Understanding of your compliance requirements (GDPR, SOC2, HIPAA)
Instructions
Step 1: Export Trace Data via API
import { LangfuseClient } from "@langfuse/client";
import { writeFileSync } from "fs";
const langfuse = new LangfuseClient();
async function exportTraces(options: {
fromDate: string;
toDate: string;
outputFile: string;
includeObservations?: boolean;
}) {
const allTraces: any[] = [];
let page = 1;
let hasMore = true;
while (hasMore) {
const result = await langfuse.api.traces.list({
fromTimestamp: options.fromDate,
toTimestamp: options.toDate,
limit: 100,
page,
});
for (const trace of result.data) {
const exportItem: any = {
id: trace.id,
name: trace.name,
timestamp: trace.timestamp,
userId: trace.userId,
sessionId: trace.sessionId,
metadata: trace.metadata,
tags: trace.tags,
};
if (options.includeObservations) {
const observations = await langfuse.api.observations.list({
traceId: trace.id,
});
exportItem.observations = observations.data;
}
allTraces.push(exportItem);
}
hasMore = result.data.length === 100;
page++;
// Rate limit respect
await new Promise((r) => setTimeout(r, 200));
}
writeFileSync(options.outputFile, JSON.stringify(allTraces, null, 2));
console.log(`Exported ${allTraces.length} traces to ${options.outputFile}`);
}
// Usage
await exportTraces({
fromDate: "2025-01-01T00:00:00Z",
toDate: "2025-01-31T23:59:59Z",
outputFile: "traces-january.json",
includeObservations: true,
});
Step 2: Export Scores
async function exportScores(fromDate: string, outputFile: string) {
const scores: any[] = [];
let page = 1;
let hasMore = true;
while (hasMore) {
const result = await langfuse.api.scores.list({
fromTimestamp: fromDate,
limit: 100,
page,
});
scores.push(...result.data);
hasMore = result.data.length === 100;
page++;
await new Promise((r) => setTimeout(r, 200));
}
writeFileSync(outputFile, JSON.stringify(scores, null, 2));
console.log(`Exported ${scores.length} scores to ${outputFile}`);
}
Step 3: Data Retention Configuration
Self-hosted: Set retention via environment variable:
# docker-compose.yml
services:
langfuse:
environmCollect Langfuse debug evidence for support tickets and troubleshooting.
Langfuse Debug Bundle
Current State
!node --version 2>/dev/null || echo 'N/A'
!python3 --version 2>/dev/null || echo 'N/A'
!npm list langfuse @langfuse/client @langfuse/tracing 2>/dev/null | head -5 || echo 'No langfuse packages'
Overview
Collect all diagnostic information needed for Langfuse support tickets: environment versions, SDK config, API connectivity, redacted logs, and a reproduction template.
Prerequisites
- Langfuse SDK installed
- Access to application logs
- Bash shell available
Instructions
Step 1: Run the Full Debug Bundle Script
Save this as langfuse-debug.sh and run it:
#!/bin/bash
set -euo pipefail
BUNDLE_DIR="langfuse-debug-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$BUNDLE_DIR"
echo "=== Langfuse Debug Bundle ===" | tee "$BUNDLE_DIR/summary.txt"
echo "Generated: $(date)" | tee -a "$BUNDLE_DIR/summary.txt"
# --- Environment ---
{
echo ""
echo "--- Environment ---"
echo "Node.js: $(node --version 2>/dev/null || echo 'not installed')"
echo "Python: $(python3 --version 2>/dev/null || echo 'not installed')"
echo "npm: $(npm --version 2>/dev/null || echo 'not installed')"
echo "OS: $(uname -srm)"
} >> "$BUNDLE_DIR/summary.txt"
# --- SDK Versions ---
{
echo ""
echo "--- SDK Versions ---"
npm list langfuse @langfuse/client @langfuse/tracing @langfuse/otel @langfuse/openai @langfuse/langchain 2>/dev/null || echo "npm: no langfuse packages"
pip show langfuse 2>/dev/null | grep -E "Name|Version" || echo "pip: langfuse not found"
} >> "$BUNDLE_DIR/summary.txt"
# --- Config (redacted) ---
{
echo ""
echo "--- Langfuse Config ---"
echo "LANGFUSE_PUBLIC_KEY: ${LANGFUSE_PUBLIC_KEY:+SET (${LANGFUSE_PUBLIC_KEY:0:12}...)}"
echo "LANGFUSE_SECRET_KEY: ${LANGFUSE_SECRET_KEY:+SET}"
echo "LANGFUSE_BASE_URL: ${LANGFUSE_BASE_URL:-NOT SET}"
echo "LANGFUSE_HOST: ${LANGFUSE_HOST:-NOT SET}"
} >> "$BUNDLE_DIR/summary.txt"
# --- Network Connectivity ---
{
echo ""
echo "--- Network Test ---"
HOST="${LANGFUSE_BASE_URL:-${LANGFUSE_HOST:-https://cloud.langfuse.com}}"
echo "Target host: $HOST"
echo -n "Health endpoint: "
curl -s -o /dev/null -w "%{http_code} (%{time_total}s)" "$HOST/api/public/health" 2>/dev/null || echo "FAILED"
echo ""
if [ -n "${LANGFUSE_PUBLIC_KEY:-}" ] && [ -n "${LANGFUSE_SECRET_KEY:-}" ]; then
AUTH=$(echo -n "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" | Deploy Langfuse with your application across different platforms.
Langfuse Deploy Integration
Overview
Deploy Langfuse LLM observability alongside your application. Covers integrating the SDK for serverless (Vercel/Lambda), Docker, Cloud Run, and self-hosting the Langfuse server itself.
Prerequisites
- Langfuse API keys (cloud or self-hosted)
- Application using Langfuse SDK
- Target platform CLI installed
Instructions
Step 1: Vercel / Next.js Deployment
set -euo pipefail
# Add secrets to Vercel
vercel env add LANGFUSE_PUBLIC_KEY production
vercel env add LANGFUSE_SECRET_KEY production
vercel env add LANGFUSE_BASE_URL production
// app/api/chat/route.ts (Next.js App Router)
import { NextRequest, NextResponse } from "next/server";
import { LangfuseClient } from "@langfuse/client";
import { startActiveObservation, updateActiveObservation } from "@langfuse/tracing";
import OpenAI from "openai";
const langfuse = new LangfuseClient();
const openai = new OpenAI();
export async function POST(req: NextRequest) {
const { messages } = await req.json();
const response = await startActiveObservation(
{ name: "chat-api", asType: "generation" },
async () => {
updateActiveObservation({
model: "gpt-4o",
input: messages,
metadata: { endpoint: "/api/chat" },
});
const result = await openai.chat.completions.create({
model: "gpt-4o",
messages,
});
updateActiveObservation({
output: result.choices[0].message,
usage: {
promptTokens: result.usage?.prompt_tokens,
completionTokens: result.usage?.completion_tokens,
},
});
return result.choices[0].message;
}
);
return NextResponse.json(response);
}
> Serverless note: Langfuse SDK v4+ uses OTel which handles flushing asynchronously. For v3, always call await langfuse.flushAsync() before the response returns -- serverless functions may freeze after response.
Step 2: AWS Lambda / Serverless
// handler.ts
import { LangfuseSpanProcessor } from "@langfuse/otel";
import { NodeSDK } from "@opentelemetry/sdk-node";
import { startActiveObservation, updateActiveObservation } from "@langfuse/tracing";
// Initialize OUTSIDE handler for connection reuse
const sdk = new NodeSDK({
spanProcessors: [
new LangfuseSpanProcessor({
exportIntervalMillis: 1000, // Flush fast in serverless
}),
],
});
sdk.start();
export const handler = async (event: any) => {
return await startActiveObservation("lambda-handler", async () => {
updateActiveObservation({ input: event });
const result = await processRequest(event);
updateActiveObservation({ ouConfigure Langfuse enterprise organization management and access control.
Langfuse Enterprise RBAC
Overview
Configure enterprise access control for Langfuse: built-in roles and permissions, scoped API keys per service, SSO integration, project-level isolation, and audit logging for compliance.
Prerequisites
- Langfuse Cloud (Team/Enterprise plan) or self-hosted instance
- Organization admin access
- SSO provider (optional, for SAML/OIDC integration)
Langfuse Built-In Roles
Langfuse provides these roles at the project level:
| Role | View Traces | Create Traces | Manage Prompts | Manage Members | Manage Billing |
|---|---|---|---|---|---|
| Owner | Yes | Yes | Yes | Yes | Yes |
| Admin | Yes | Yes | Yes | Yes | No |
| Member | Yes | Yes | Yes | No | No |
| Viewer | Yes | No | No | No | No |
Instructions
Step 1: Organization and Project Structure
Organization: Acme Corp
├── Project: production-chatbot
│ ├── Owner: engineering-lead@acme.com
│ ├── Admin: senior-dev@acme.com
│ ├── Member: developer@acme.com
│ └── API Key: sk-lf-prod-chatbot-...
│
├── Project: staging-chatbot
│ ├── Admin: senior-dev@acme.com
│ ├── Member: developer@acme.com
│ └── API Key: sk-lf-staging-chatbot-...
│
└── Project: analytics-readonly
├── Admin: data-lead@acme.com
├── Viewer: analyst@acme.com
└── API Key: sk-lf-analytics-...
Best practice: Separate projects for production, staging, and analytics. Never share API keys across environments.
Step 2: Scoped API Keys
Create API keys with specific purposes and rotate regularly:
// In Langfuse UI: Settings > API Keys > Create
// Each key pair (public + secret) is scoped to one project
// Service-specific keys
// Backend API: pk-lf-prod-api-... / sk-lf-prod-api-...
// CI/CD pipeline: pk-lf-ci-... / sk-lf-ci-...
// Analytics: pk-lf-analytics-... / sk-lf-analytics-...
// Validate key scope at startup
function validateApiKeyScope(expectedProject: string) {
const pk = process.env.LANGFUSE_PUBLIC_KEY || "";
if (!pk.includes(expectedProject)) {
console.warn(
`WARNING: API key may not match expected project: ${expectedProject}`
);
}
}
// Key rotation script
async function rotateApiKeys() {
// 1. Create new key pair in Langfuse UI
// 2. Deploy new keys to secret manager
// 3. Wait for all instances to pick up new keys
// 4. Revoke old key pair in Langfuse UI
console.log("Key rotation checklist:");
console.log("1. [ ] New key pair created in Langfuse");
console.lCreate a minimal working Langfuse trace example.
Langfuse Hello World
Overview
Create your first Langfuse trace with real SDK calls. Demonstrates the trace/span/generation hierarchy, the observe wrapper, and the OpenAI drop-in integration.
Prerequisites
- Completed
langfuse-install-authsetup - Valid API credentials in environment variables
- OpenAI API key (for the OpenAI integration example)
Instructions
Step 1: Hello World with v4+ Modular SDK
// hello-langfuse.ts
import { startActiveObservation, observe, updateActiveObservation } from "@langfuse/tracing";
import { LangfuseSpanProcessor } from "@langfuse/otel";
import { NodeSDK } from "@opentelemetry/sdk-node";
// Register OpenTelemetry processor (once at startup)
const sdk = new NodeSDK({
spanProcessors: [new LangfuseSpanProcessor()],
});
sdk.start();
async function main() {
// Create a top-level trace with startActiveObservation
await startActiveObservation("hello-world", async (span) => {
span.update({
input: { message: "Hello, Langfuse!" },
metadata: { source: "hello-world-example" },
});
// Nested span -- automatically linked to parent
await startActiveObservation("process-input", async (child) => {
child.update({ input: { text: "processing..." } });
await new Promise((r) => setTimeout(r, 100));
child.update({ output: { result: "done" } });
});
// Nested generation (LLM call tracking)
await startActiveObservation(
{ name: "llm-response", asType: "generation" },
async (gen) => {
gen.update({
model: "gpt-4o",
input: [{ role: "user", content: "Say hello" }],
output: { content: "Hello! How can I help you today?" },
usage: { promptTokens: 5, completionTokens: 10, totalTokens: 15 },
});
}
);
span.update({ output: { status: "completed" } });
});
// Allow time for the span processor to flush
await sdk.shutdown();
console.log("Trace created! Check your Langfuse dashboard.");
}
main().catch(console.error);
Step 2: Hello World with observe Wrapper
The observe wrapper traces existing functions without modifying internals:
import { observe, updateActiveObservation } from "@langfuse/tracing";
// Wrap any async function -- it becomes a traced span
const processQuery = observe(async (query: string) => {
updateActiveObservation({ input: { query } });
// Simulate processing
const result = `Processed: ${query}`;
updateActiveObservation({ output: { result } });
return result;
});
// Wrap an LLM call as a generation
const generateAnswer = observe(
{ name: "Troubleshoot and respond to Langfuse-related incidents and outages.
Langfuse Incident Runbook
Overview
Step-by-step procedures for Langfuse-related incidents, from initial triage (2 min) through resolution and post-incident review. Your application should work without Langfuse -- these procedures focus on restoring observability.
Severity Classification
| Severity | Description | Response Time | Example |
|---|---|---|---|
| P1 | Application impacted by tracing | 15 min | SDK throwing unhandled errors, blocking requests |
| P2 | Traces not appearing, no app impact | 1 hour | Missing observability data |
| P3 | Degraded performance from tracing | 4 hours | High latency from flush backlog |
| P4 | Minor issues | 24 hours | Occasional missing traces |
Instructions
Step 1: Initial Assessment (2 Minutes)
set -euo pipefail
echo "=== Langfuse Incident Triage ==="
echo "Time: $(date -u)"
# 1. Check Langfuse cloud status
echo -n "Status page: "
curl -s -o /dev/null -w "%{http_code}" https://status.langfuse.com || echo "UNREACHABLE"
echo ""
# 2. Test API connectivity
HOST="${LANGFUSE_BASE_URL:-${LANGFUSE_HOST:-https://cloud.langfuse.com}}"
echo -n "API health: "
curl -s -o /dev/null -w "%{http_code} (%{time_total}s)" "$HOST/api/public/health" || echo "FAILED"
echo ""
# 3. Test auth
if [ -n "${LANGFUSE_PUBLIC_KEY:-}" ] && [ -n "${LANGFUSE_SECRET_KEY:-}" ]; then
AUTH=$(echo -n "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" | base64)
echo -n "Auth test: "
curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: Basic $AUTH" "$HOST/api/public/traces?limit=1" || echo "FAILED"
echo ""
fi
# 4. Check app error logs
echo ""
echo "--- Recent errors ---"
grep -i "langfuse\|trace.*error\|flush.*fail" /var/log/app/*.log 2>/dev/null | tail -10 || echo "No log files found"
Step 2: Determine Incident Type and Response
| Symptom | Likely Cause | Immediate Action | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| No traces appearing | SDK not flushing | Check shutdown handlers; set flushAt: 1 temporarily |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
401 Unauthorized |
Key rotation or mismatch | Verify keys match the correct project | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
429 Too Many Requests |
Rate limited | Increase batch size, reduce flush frequency | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SDK throwing errors | Unhandled exception | Wrap in try/catch; check SDK version | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| High request latency
Install and configure Langfuse SDK authentication for LLM observability.
ReadWriteEditBash(npm:*)Bash(pip:*)Bash(pnpm:*)Grep
Langfuse Install & AuthOverviewInstall the Langfuse SDK and configure authentication for LLM observability. Covers both the legacy Prerequisites
InstructionsStep 1: Install SDKTypeScript/JavaScript (v4+ modular SDK -- recommended):
TypeScript/JavaScript (v3 legacy -- single package):
Python:
Step 2: Get API Keys
Step 3: Configure Environment Variables
> Note: v4+ uses Step 4: Initialize and Verify (v4+ Modular SDK)Set up Langfuse local development workflow with hot reload and debugging.
ReadWriteEditBash(npm:*)Bash(docker:*)Bash(pnpm:*)
Langfuse Local Dev LoopOverviewFast local development workflow with Langfuse tracing, immediate trace visibility, debug logging, and optional self-hosted local instance via Docker. Prerequisites
InstructionsStep 1: Development Environment File
Step 2: Dev-Optimized Langfuse Setup (v4+)
Step 3: Dev-Optimized Setup (v3 Legacy)
Step 4: Hot Reload Scripts
Step 5: Development Tracing UtiExecute complex Langfuse migrations including data migration and platform changes.
ReadWriteEditBash(npm:*)
Langfuse Migration Deep DiveCurrent State! OverviewComprehensive guide for complex migrations: cloud-to-self-hosted, LangSmith-to-Langfuse, cross-instance data migration, and zero-downtime dual-write patterns. Prerequisites
Migration Scenarios
InstructionsStep 1: Export Data from Source InstanceConfigure Langfuse across development, staging, and production environments.
ReadWriteEditBash(aws:*)Bash(gcloud:*)Bash(vault:*)
Langfuse Multi-Environment SetupOverviewConfigure Langfuse across dev/staging/production with isolated API keys, environment-specific SDK settings, secret management, and CI/CD integration to prevent cross-environment data leakage. Prerequisites
Environment Strategy
InstructionsStep 1: Environment-Specific ConfigurationSet up comprehensive observability for Langfuse with metrics, dashboards, and alerts.
ReadWriteEdit
Langfuse ObservabilityOverviewSet up monitoring for your Langfuse integration: Prometheus metrics for trace/generation throughput, Grafana dashboards, alert rules, and integration with Langfuse's built-in analytics dashboards and Metrics API. Prerequisites
InstructionsStep 1: Langfuse Built-In DashboardsLangfuse provides pre-built dashboards in the UI at
Accessing via Metrics API:
Step 2: Prometheus Metrics for Your AppTrack the health of your Langfuse integration with custom Prometheus metrics: Optimize Langfuse tracing performance for high-throughput applications.
ReadWriteEdit
Langfuse Performance TuningOverviewOptimize Langfuse tracing for minimal overhead and maximum throughput: benchmark measurement, batch tuning, non-blocking patterns, payload optimization, sampling, and memory management. Prerequisites
Performance Targets
InstructionsStep 1: Benchmark Current Performance
Step 2: Optimize Batch Configuration
Langfuse production readiness checklist and verification.
ReadWriteEditBash(npm:*)Grep
Langfuse Production ChecklistOverviewComprehensive checklist for deploying Langfuse observability to production with verified configuration, error handling, graceful shutdown, monitoring, and a pre-deployment verification script. Prerequisites
Production ConfigurationRecommended SDK Settings
Production Error Handling
Pre-Deployment Verification ScriptImplement Langfuse rate limiting, batching, and backoff patterns.
ReadWriteEdit
Langfuse Rate LimitsOverviewHandle Langfuse API rate limits with optimized SDK batching, exponential backoff with jitter, concurrent request limiting, and configurable sampling for ultra-high-volume workloads. Prerequisites
InstructionsStep 1: Optimize SDK Batching ConfigurationThe Langfuse SDK batches events internally before sending. Tuning batch settings is the first defense against rate limits.
Step 2: Implement Retry with Exponential BackoffFor custom API calls (scores, datasets, prompts) that hit rate limits: Production-grade Langfuse architecture patterns and best practices.
ReadWriteEdit
Langfuse Reference ArchitectureOverviewProduction-grade architecture patterns for Langfuse LLM observability: singleton SDK, context propagation with Prerequisites
Architecture Tiers
InstructionsPattern 1: Singleton SDK with Context Propagation
Pattern 2: Express Middleware for Automatic TracingLangfuse SDK best practices, patterns, and idiomatic usage.
ReadWriteEdit
Langfuse SDK PatternsOverviewProduction-quality patterns for the Langfuse SDK: singleton clients, the Prerequisites
InstructionsPattern 1: Singleton Client with Graceful Shutdown
Legacy v3 singleton:
Pattern 2:
|
| SDK | Package | Architecture | Status |
|---|---|---|---|
| v3 | langfuse (single) |
Custom, Langfuse class |
Legacy |
| v4 | @langfuse/client, @langfuse/tracing, @langfuse/otel |
OpenTelemetry-based | Stable |
| v5 | @langfuse/client, @langfuse/tracing, @langfuse/otel |
OpenTelemetry + improvements | Latest |
Instructions
Step 1: Check Current Version and Plan
set -euo pipefail
# Check what you have
npm list langfuse @langfuse/client @langfuse/tracing 2>/dev/null
# Check latest available
npm info @langfuse/client version
npm info @langfuse/tracing version
npm info langfuse version
# Python
pip show langfuse 2>/dev/null | grep Version
pip index versions langfuse 2>/dev/null | head -3
Step 2: v3 to v4 Migration (TypeScript)
This is the biggest migration -- v4 rewrites tracing on OpenTelemetry.
2a. Install new packages:
set -euo pipefail
# Install v4+ packages
npm install @langfuse/client @langfuse/tracing @langfuse/otel @opentelemetry/sdk-node
# Keep langfuse v3 temporarily for comparison
# Remove after migration: npm uninstall langfuse
2b. Update initialization:
// BEFORE (v3):
import { Langfuse } from "langfuse";
const langfuse = new Langfuse({
publicKey: process.env.LANGFUSE_PUBLIC_KEY,
secretKey: process.env.LANGFUSE_SECRET_KEY,
baseUrl: process.env.LANGFUSE_HOST,
});
// AFTER (v4+):
import { LangfuseClient } from "@langfuse/client";
import { LangfuseSpanProcessor } from "@langfuse/otel";
import { NodeSDK } from "@opentelemetry/sdk-node";
// OTel setup (once at entry point)
const sdk = new NodeSDK({
spanProcessors: [new LangfuseSpanProcessor()],
});
sdk.start();
// Client for prompts, datasets, scores
const langfuse = new LangfuseClient();
2c. Update tracing calls:
Configure Langfuse webhooks for prompt change notifications and event-driven workflows.
Langfuse Webhooks & Events
Overview
Configure Langfuse webhooks to receive notifications on prompt version changes. Langfuse supports webhook events for prompt lifecycle: Created, Updated (labels/tags changed), and Deleted. Use webhooks to trigger CI/CD pipelines, sync prompts to external systems, or notify teams via Slack.
Prerequisites
- Langfuse Cloud or self-hosted instance
- HTTPS endpoint to receive webhook POST requests
- Webhook secret for HMAC signature verification
Instructions
Step 1: Create Webhook Endpoint
// app/api/webhooks/langfuse/route.ts (Next.js App Router)
import { NextRequest, NextResponse } from "next/server";
import crypto from "crypto";
const WEBHOOK_SECRET = process.env.LANGFUSE_WEBHOOK_SECRET!;
interface LangfuseWebhookEvent {
event: "prompt.created" | "prompt.updated" | "prompt.deleted";
timestamp: string;
data: {
promptName: string;
promptVersion: number;
labels?: string[];
projectId: string;
[key: string]: any;
};
}
// Verify HMAC SHA-256 signature
function verifySignature(payload: string, signature: string): boolean {
const expected = crypto
.createHmac("sha256", WEBHOOK_SECRET)
.update(payload)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
export async function POST(request: NextRequest) {
const payload = await request.text();
const signature = request.headers.get("x-langfuse-signature");
// Verify webhook authenticity
if (!signature || !verifySignature(payload, signature)) {
return NextResponse.json({ error: "Invalid signature" }, { status: 401 });
}
const event: LangfuseWebhookEvent = JSON.parse(payload);
console.log(`Langfuse webhook: ${event.event} - ${event.data.promptName}`);
switch (event.event) {
case "prompt.created":
await handlePromptCreated(event.data);
break;
case "prompt.updated":
await handlePromptUpdated(event.data);
break;
case "prompt.deleted":
await handlePromptDeleted(event.data);
break;
}
return NextResponse.json({ received: true });
}
async function handlePromptCreated(data: LangfuseWebhookEvent["data"]) {
// Trigger CI/CD pipeline for new prompt version
if (data.labels?.includes("production")) {
await triggerPromptDeployPipeline(data.promptName, data.promptVersion);
}
await notifySlack({
text: `New prompt version: *${data.promptName}* v${data.promptVersion}`,
labels: data.labels,
});
}
async function handlePromptUpdated(data: LangfuseWebhookEvent["data"]) {
// Label change -- check if promoted to production
if (data.labels?.includes("production")) {
awaReady to use langfuse-pack?
Related Plugins
ai-ethics-validator
AI ethics and fairness validation
ai-experiment-logger
Track and analyze AI experiments with a web dashboard and MCP tools
ai-ml-engineering-pack
Professional AI/ML Engineering toolkit: Prompt engineering, LLM integration, RAG systems, AI safety with 12 expert plugins
ai-sdk-agents
Multi-agent orchestration with AI SDK v5 - handoffs, routing, and coordination for any AI provider (OpenAI, Anthropic, Google)
anomaly-detection-system
Detect anomalies and outliers in data
automl-pipeline-builder
Build AutoML pipelines