← Back to Home

Claude Code + n8n + Langfuse Hands-On

LangfuseClaude Coden8nLLM observabilityOllamaself-hostedAI coding

When Claude Code calls a local Ollama model, Token usage goes dark, latency spikes have no root cause, and error rates can't be attributed — problems that get worse once you leave the cloud and self-host everything. This article builds a Claude Code + n8n + Langfuse stack that uses Langfuse's OTEL traces to cover the full链路 from Prompt input to workflow execution, so every Claude Code call leaves a trace.

Architecture Overview

Three-piece data flow:

Claude Code (Prompt input)
  ↓ HTTP (OpenAI-compatible API)
Ollama (local LLM)
  ↓ OTEL Trace
Langfuse (self-hosted, port 3000)
  ↓ Trigger
n8n (listening to Langfuse Webhook)
  ↓ Action
Workflow execution (Slack notification / Notion log / CI trigger)

Prerequisites

Step 1: Deploy Langfuse Self-Hosted

Langfuse's official Docker Compose template is more controllable than Vercel deployment (no data leaving your server).

mkdir -p ~/langfuse && cd ~/langfuse
# Download official template
curl -fsSL https://langfuse.com/self-hosting/docker -o docker-compose.yml
# Set environment variables
export SECRET_KEY=local-dev-secret-change-in-prod
export DATABASE_URL=postgresql://postgres:postgres@localhost:5432/langfuse
export NEXTAUTH_SECRET=local-auth-secret
# Start
docker compose up -d
# Verify
curl -s http://localhost:3000/api/public/health | python3 -m json.tool

Output example:

{"status":"ok","version":"3.14.2"}

Langfuse dashboard: http://your-server:3000. The first registered user becomes admin.

Step 2: Configure Claude Code to Connect to Ollama

Claude Code talks to Ollama via the OpenAI-compatible API — no plugins needed.

# Set environment variables (add to ~/.bashrc)
export OLLAMA_BASE_URL=http://localhost:11434/v1
export OPENAI_API_KEY=local-dev
export MODEL=llama3.2:3b

# Test in Claude Code
claude "What is 2+2?" --output-format stream

If you see Connection refused, verify Ollama is listening:

curl http://localhost:11434/api/tags

Step 3: Inject Langfuse Python SDK Traces

Instrument your Claude Code call scripts with the Langfuse SDK:

# my_script.py
from langfuse import Langfuse
import os

langfuse = Langfuse(
    public_key=os.environ["LANGFuse_PUBLIC_KEY"],
    secret_key=os.environ["LANGFUSE_SECRET_KEY"],
    host="http://your-langfuse-server:3000"
)

def call_llm(prompt):
    with langfuse.start_span(name="ollama-call") as span:
        span.input = prompt
        # Actually call Ollama (via OpenAI SDK)
        response = openai.ChatCompletion.create(
            model=os.environ["MODEL"],
            messages=[{"role":"user","content":prompt}],
            api_base=os.environ["OLLAMA_BASE_URL"],
            api_key=os.environ["OPENAI_API_KEY"]
        )
        span.output = response["choices"][0]["message"]["content"]
        return response["choices"][0]["message"]["content"]

Step 4: n8n Listens to Langfuse Webhooks

Langfuse supports webhook callbacks; n8n receives them and triggers downstream actions (Slack alerts, Notion logs, CI pipelines).

# n8n self-hosted (continued from 6/15 n8n + Langfuse hands-on)
mkdir -p ~/n8n && cd ~/n8n
curl -fsSL https://raw.githubusercontent.com/n8n-io/n8n/master/docker-compose.yml -o docker-compose.yml
# Add Langfuse Webhook Node
# n8n dashboard → Workflows → New → Webhook (langfuse-events)
# Trigger URL: https://your-langfuse.com/api/public/ingestion

n8n workflow example: when Langfuse records an LLM call with latency > 5000ms, send a Slack alert:

[Webhook Trigger] → [IF: trace.latency > 5000] → [Slack Node: @here High Latency Alert]

💣 Pitfall Survival Guide

Pitfall 1: Ollama Port 11434 Not Listening on All Interfaces

**Error**: ECONNREFUSED 127.0.0.1:11434

**Cause**: Ollama binds to 127.0.0.1 by default — Docker containers on the host can't reach it.

**Fix**: Set OLLAMA_HOST=0.0.0.0:

# Edit systemd service
sudo systemctl edit ollama
# Add:
[Service]
Environment="OLLAMA_HOST=0.0.0.0"
# Reload
sudo systemctl daemon-reload && sudo systemctl restart ollama

Pitfall 2: Langfuse Port 3000 Conflict with Docker Default

**Error**: port is already allocated

Cause: Some Docker images default to port 3000 (Flask/Remnia etc.).

Fix:

# Method 1: Remap Langfuse ports
# In docker-compose.yml:
services:
  langfuse:
    ports:
      - "3000:3000"
      - "3001:3001"
# Update DATABASE_URL to use 5432 (PostgreSQL default)

# Method 2: Find the conflicting process
sudo lsof -i :3000

Pitfall 3: Langfuse Python SDK Model Name Mismatch with Ollama

**Symptom**: Trace shows in Langfuse dashboard, but model name shows as unknown.

**Cause**: Ollama returns model names in format llama3.2:3b, which Langfuse SDK doesn't auto-detect.

Fix: Explicitly pass model in span metadata:

with langfuse.start_span(
    name="ollama-call",
    metadata={"model": os.environ["MODEL"]}
) as span:
    ...

Pitfall 4: n8n Webhook Timeout (Langfuse Default 30s)

**Error**: RequestTimeoutError: Webhook request timeout

Cause: Langfuse webhook default timeout is 30s, but complex n8n workflows often exceed this.

Fix: Either increase timeout in Langfuse dashboard → Settings → Webhooks, or switch to async trigger:

[Webhook] → [Node: Delay 0] → [Node: HTTP Request (Langfuse ACK)]

Pitfall 5: Langfuse PostgreSQL Connection Pool Exhaustion (High-Frequency Calls)

**Error**: remaining connection slots are reserved

**Cause**: Langfuse self-hosted defaults to max_connections=20. High-frequency Claude Code calls (100+/min) burn through this fast.

Fix:

# In docker-compose.yml PostgreSQL section, add:
environment:
  POSTGRES_MAX_CONNECTIONS: 100
# Or directly:
ALTER SYSTEM SET max_connections = 100;
sudo systemctl restart postgresql

Before vs After Comparison

DimensionWithout LangfuseWith Langfuse
Token usage transparencyBlack boxFull trace per call
Latency analysisGut feelingP50/P95/P99 auto-calculated
Error rate trackingLog searchingDashboard real-time alerts
n8n automation triggerCustom monitoringWebhook native integration
Cost attributionRough estimateTrace-level precision

Summary

The Claude Code + n8n + Langfuse three-piece stack turns the local LLM call black box transparent: Langfuse records every call, n8n triggers downstream workflows based on trace results, forming a complete closed loop of "LLM call → observability tracing → automated response."

If you're running models locally, start with Langfuse self-hosted (30 minutes to up and running), then gradually integrate n8n for alerting and workflow automation.

Related Reading:

👉 Join MiniMax Token Plan: AI coding acceleration for businesses

👉 Join Zhipu Coding Plan: GLM-4.6/GLM-5 coding packages, China-stable, pay-per-token unlimited

👉 Join Aliyun AI: Top AI products with exclusive coupons for business innovation

📌 This article was AI-assisted generated and human-reviewed | TechPassive — An AI-driven content testing site focused on real tool reviews

🔗 Recommended Tools

These are carefully selected tools. Using our affiliate links supports us to keep producing quality content:

☁️ DigitalOcean Cloud ⚡ Vultr VPS ⭐ MiniMax Token Plan 🧩 Zhipu Coding Plan 🎁 Zhipu 20M Tokens Gift 🤖 QoderWork CN (Refer & Earn) ☁️ Aliyun AI Products 📚 WordPress Books 🔍 WordPress SEO Books 🌐 Web Hosting Books 🐳 Docker Books 🐧 Linux Books 🐍 Python Books 💰 Affiliate Marketing 💵 Passive Income Books 🖥️ Server Books ☁️ Cloud Computing Books 🚀 DevOps Books
← Back to Home