Langfuse Self-Hosted, LLM Observability On Your Own Box
Langfuse v3 self-host on a Linux VM, the install I shipped for a client's Claude-driven product

Langfuse is the open-source observability layer that turns "my LLM app is slow but I do not know why" into "trace 4f3a took 8.2s of which 6.1s was a long Claude call with a prompt that was 14k tokens too big". Self-hosted, it gives you the same dashboards as the SaaS without sending production data outside your infra. I shipped a Langfuse install for a client running Claude in production. This is the setup.
What you'll build
Langfuse v3 self-hosted on a Linux VM, accessible from your dev machine, with a sample Anthropic Python script reporting traces. Roughly 30 minutes.
Caption: Langfuse showing traces, costs, and latency for a Claude-driven app.
Prerequisites
- A Linux VM with at least 4GB RAM (I run mine on Oracle ARM free tier)
- PostgreSQL 14+ available (Langfuse needs this; install or point at an existing one)
- Node 20+ and the Langfuse repo cloned
- Anthropic API key for testing instrumentation
- 10GB free disk
The Langfuse v3 self-host uses ClickHouse plus Postgres for the analytics path. Plan for that footprint.
Step 1, set up the database
If you already run Postgres, create a database for Langfuse:
sudo -u postgres psql
CREATE DATABASE langfuse;
CREATE USER langfuse_user WITH PASSWORD 'a-strong-password';
GRANT ALL PRIVILEGES ON DATABASE langfuse TO langfuse_user;
\q

If you do not run Postgres, install it first: sudo apt install postgresql-14.
Step 2, clone Langfuse and install
cd ~/tools
git clone https://github.com/langfuse/langfuse.git
cd langfuse
npm install

The npm install is roughly 1.5GB and takes 5-7 minutes. Langfuse uses pnpm internally; the wrapper handles the right invocation.
Step 3, set environment variables
Create .env:
DATABASE_URL=postgresql://langfuse_user:a-strong-password@localhost:5432/langfuse
NEXTAUTH_URL=http://thinkcentre.local:3000
NEXTAUTH_SECRET=$(openssl rand -base64 32)
SALT=$(openssl rand -base64 16)
ENCRYPTION_KEY=$(openssl rand -hex 32)

The encryption key is used to encrypt API keys and other secrets at rest in the DB. Back it up.
Step 4, run migrations and start
npx prisma migrate deploy
npm run build
npm run start

The first start runs the migrations and seeds the DB. Open http://thinkcentre.local:3000 to see the sign-up page.
Step 5, instrument a Python script
Sign up, create a project, copy the public and secret keys. Install the Langfuse Python SDK:
pip install langfuse anthropic
import os
from langfuse.decorators import observe
from langfuse.anthropic import Anthropic
from anthropic import Anthropic as AnthropicRaw
# Wrapped client emits traces automatically
client = Anthropic()
@observe()
def summarise(text: str) -> str:
resp = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=200,
messages=[{"role": "user", "content": f"Summarise: {text}"}],
)
return resp.content[0].text
print(summarise("FastAPI is a Python web framework..."))

Set the env vars before running:
export LANGFUSE_PUBLIC_KEY="pk-lf-..."
export LANGFUSE_SECRET_KEY="sk-lf-..."
export LANGFUSE_HOST="http://thinkcentre.local:3000"
export ANTHROPIC_API_KEY="sk-ant-..."
python summarise.py
The trace appears in the Langfuse dashboard within a few seconds.
First run
A real production-shape workflow:
[FastAPI app with /chat endpoint]
-> wrapped Anthropic client emits traces
-> Langfuse dashboard shows: latency, cost, prompt, response
-> filter by user_id, time, model
-> debug slow requests

For a client product I shipped, this took the support workflow from "logs are 500MB plain text" to "trace ID 4f3a, here is the slow prompt".
What broke for me
Two real issues. First, the Langfuse v3 ClickHouse migration on Oracle ARM was rough; the ClickHouse Linux ARM binary did not exist for the version Langfuse pinned. The fix was using the v2 self-host (Postgres-only, no ClickHouse) for ARM, which is feature-complete enough for most observability needs. The cost was no analytics-aggregation features, which I did not need at low volume anyway.
Second, the Anthropic wrapping pattern (from langfuse.anthropic import Anthropic) was missing in the Langfuse SDK version I first installed. The fix was upgrading to langfuse>=2.50.0. The decorator-only pattern (@observe()) works on any client but produces less structured traces; the wrapped client is worth the upgrade.
What it costs
| Item | Cost |
|---|---|
| Langfuse self-hosted | Free (MIT) |
| Langfuse Cloud (alternative) | $59/mo Pro tier |
| Postgres | Free |
| Hosting (Oracle ARM free) | Rs 0/mo |
| Storage (Postgres) | ~10MB per 10k traces |
For a small Indian SaaS shipping AI features, self-hosted Langfuse at Rs 0/mo against the cloud version's $59/mo is a clear win unless you need the cloud's enterprise features.
When NOT to use this
Skip self-hosted Langfuse if your team does not have an ops engineer comfortable with Postgres ops. Langfuse Cloud is the right path for teams without that capacity.
Skip if your LLM volume is under ~100 calls a day. Plain logging plus a print in your script is enough at that scale; observability infrastructure is overhead.
Indian operator angle
For Indian SaaS shops shipping production AI features, self-hosted Langfuse is the cleanest data-residency story. Customer prompts and Anthropic responses stay on your VM; the Langfuse cloud route would push them to EU or US infra, which some Indian compliance reviews flag.
The Oracle Cloud free-tier ARM VM (4 cores, 24GB RAM) is genuinely free forever and runs Langfuse v2 self-host without issues. For an Indian dev team wanting to ship LLM observability without budget, this is the path.
Related
More Automation

Cloudflare API Token Gotchas: The PUT That Wiped Mine Twice
I broke production twice by updating a Cloudflare token's scopes through the public API, then learned the wrangler auth fix and a secret-scrub habit the hard way. This is exactly what bit me and how I handle tokens now.

Fix NVIDIA Cursor and Video Stutter on Linux: GPU Clock Thrash
Cursor jitter and dropped video frames on NVIDIA Linux get blamed on the compositor every time. On my GTX 1660 the real cause was the driver bouncing graphics and VRAM clocks under light load. Here is the fix that held.

Litestream to Cloudflare R2: Disaster Recovery for SQLite
SQLite on one free box is one disk failure away from gone. Here is the exact Litestream-to-R2 setup I run across every PocketBase backend in my stack, including the restore drill and the gotcha that bites first.