The short version: On July 29, 2026, the self-hosted Langfuse server hit stable v4.0.0 — with v4.1.0 and v4.2.0 following on the next two days. When Langfuse cut the release candidates we said one thing: wait for stable, rehearse the migration, don't point production at an RC. Stable is here, so the waiting is over and the migration is the job. The catch that made us cautious hasn't changed — v4 drops superseded Postgres and ClickHouse tables, and that's a one-way trip. Here's the order of operations that gets you across it without losing a trace.
First, the version trap (30 seconds, saves an afternoon)#
The server and the Python SDK both have a "v4," and they are unrelated. The SDK — the package your app imports to emit traces — has been on its own v4.x line for a while, and a v4 SDK already talks to a v3 server. This migration is only about the server: the application you deploy with its Postgres and ClickHouse backends. Upgrading one does not force the other. We laid this out in full in the RC piece; if you only remember one thing, remember that upgrading your SDK did not just migrate your server.
What you're getting, and what you're risking#
Getting: full-text search across inputs, outputs, and metadata; the filter search bar; monitors and alerts; and the faster Observations API v2 and Metrics API v2 — features that were effectively enterprise-only before. If you self-host to dodge per-trace cloud pricing, this is the release that closes most of the gap.
Risking: a destructive, one-way schema migration. v4 drops the old Postgres and ClickHouse tables v3 relied on. There is no clean rollback by repointing a v3 container at the same database — the tables it needs are gone. Your backup is your only rollback.
A destructive migration isn't dangerous because it's hard. It's dangerous because it's irreversible in place. Rehearse it once on a copy and it becomes routine; run it blind on production and there's no undo.
The migration, in order#
Step 0 — Read the real guide. Langfuse ships an official v3→v4 upgrade guide that carries the exact migration order and any version-pinning notes. Nothing below replaces it — this is the operational wrapper around it.
Step 1 — Back up both datastores. The migration touches Postgres and ClickHouse, so back up both, together, from a consistent point.
# Postgres
pg_dump "$LANGFUSE_POSTGRES_URL" -Fc -f langfuse-pg-$(date +%F).dump
# ClickHouse (use your deployment's backup mechanism — e.g. clickhouse-backup,
# or a volume snapshot if you run it as a container)
clickhouse-backup create langfuse-v3-$(date +%F)
Verify the dumps are non-empty and restorable before you touch anything else. A backup you haven't test-restored is a hope, not a rollback.
Step 2 — Stand up a staging instance from the backup. Restore both dumps into a throwaway environment that mirrors production — same data volume, different machine. This is the copy you're allowed to break.
Step 3 — Run the migration on staging and time it. Pull the v4 images and bring the stack up so the migration runs, following the upgrade guide's order:
# pin to the stable tag, don't float to :latest for a destructive upgrade
export LANGFUSE_VERSION=4.2.0
docker compose pull
docker compose up -d # migration runs on startup, per the upgrade guide
docker compose logs -f langfuse-web # watch the migration to completion
Note how long it takes on production-sized data. A migration that's instant on a toy dataset can run for many minutes on real trace volume, and that number decides your maintenance window.
Step 4 — Verify on staging. Open the UI and confirm the things that would quietly break: historical traces resolve, dashboards render, evals/scores are intact, and new ingestion lands. If anything is missing, you found it on a copy — exactly the point.
Step 5 — Cut over production. Schedule a quiet window sized to your Step 3 timing. Take a fresh backup, deploy v4, let the migration run once, watch ingestion resume, and re-run your Step 4 checks against production. Then, and only then, retire the v3 images.
The rule under all of it#
You are not upgrading a stateless web app; you are performing a one-way database migration on your observability system of record. Treat the backup as the product of Step 1, the staging rehearsal as non-negotiable, and the stable tag as permission to start — not permission to skip the rehearsal. Do that and v4's search, monitors, and faster APIs are a quiet Tuesday. Skip it and they're an incident.



