Langfuse v4 cambia la tabla de la que lee las trazas, y pasar de v3 a v4 no se resuelve cambiando la etiqueta de la imagen. Esta guía explica la migración completa de una instalación con Docker Compose: primero ClickHouse, después el servidor en modo de doble escritura, el relleno del histórico y el corte final. La ejecuté entera el 16 de septiembre de 2026, de Langfuse v3.225.8 a v4.37.0, con datos de tres versiones del SDK de Python. Aquí están los tiempos, los errores y los detalles que la guía oficial no cuenta. Si todavía no conoces la herramienta, empieza por qué es Langfuse y cómo se despliega.

Puntos clave

  • La v4 lee de una tabla nueva de ClickHouse, events_full. Tras el corte al modo por defecto (events_only), el SDK de Python v2 recibe errores 400, y la guía lista 22 endpoints de la API pública que pasan a devolver 404.
  • La etiqueta latest y el docker-compose.yml del repositorio ya apuntan a la v4, así que docker compose up --pull always te sube de versión sin modo de transición. Fija las etiquetas antes de empezar.
  • El compose de v3 usaba ClickHouse sin etiqueta (hoy, la 26.8) y el de v4 fija la 25.12. Con datos que ya había abierto la 26.8, la 25.12 no arranca.
  • Si tienes productores con el SDK de Python v3, activa LANGFUSE_MIGRATION_V4_NATIVE_OTEL_BEHAVIOUR=dual_write desde el primer arranque de v4. Sin esa variable, sus observaciones hijas quedan sin usuario ni sesión, y el relleno del histórico no lo corrige.
  • Con 45 931 trazas, el relleno tardó 3 min 5 s, y durante el proceso las tablas de trazas ocuparon 3,55 veces su tamaño inicial. Volver a v3 sin restaurar la copia funciona (migrate goto 37 tardó 2,4 s), pero lo escrito después del corte se pierde.

Qué cambia en Langfuse v4 y a quién afecta

Langfuse v4 guarda cada llamada al modelo, cada herramienta y cada paso del agente como una fila de events_full, una tabla ancha y casi inmutable. Cada fila lleva copiados los atributos de la traza: usuario, sesión y etiquetas. Una segunda tabla, events_core, es una proyección recortada que sirve las tablas y los gráficos, y cada traza pasa a ser la observación raíz de su árbol.

Según el artículo técnico de Langfuse[1], así se evitan las uniones y la deduplicación en cada lectura, y los paneles de proyectos grandes cargan "at least 10x" más rápido. Es una cifra del fabricante que no he medido.

Las fechas que importan son tres:

  • 29 de julio de 2026: se publica Langfuse v4.0.0[2]
  • 16 de noviembre de 2026: Langfuse Cloud pasa a ser solo v4, según el anuncio de la versión 4[3]
  • Enero de 2027: último mes de parches de seguridad para la v3 autoalojada

La guía oficial de migración[4] lo dice así: "Langfuse v3 will receive security patches until end of January 2027". Si alojas Langfuse tú mismo, no hay fecha de corte obligatoria, pero la v3 ya solo recibe parches: la v3.225.8, del 16 de septiembre, trae tres correcciones portadas desde la v4.

Lo que se rompe depende de tus clientes. Esta es la matriz de compatibilidad[5] resumida para un servidor v4:

Cliente En un servidor v4 Qué hacer
SDK de Python 4.7.0 o superior, JS/TS 5.4.0 o superior Soporte completo, escritura directa Nada
SDK de Python 4.0 a 4.6, JS/TS 5.0 a 5.3 Funciona, con retraso durante la doble escritura Subir al mínimo
SDK de Python v3, JS/TS v4 Obsoleto Migrar a Python v4 o JS/TS v5
SDK de Python v2, JS/TS v3 Sin soporte tras el corte Migrar antes del corte
OpenTelemetry directo Soporte completo Enviar la cabecera x-langfuse-ingestion-version: 4

Tras el corte también dejan de funcionar los evaluadores con juez LLM asociados a la traza y la exportación "Traces and observations (legacy)" hacia almacenamiento, PostHog o Mixpanel. Si tus agentes ya usan OpenTelemetry con las convenciones GenAI, llevas la mitad del trabajo hecho.

Por qué no debes actualizar con docker compose up –pull always

La guía de despliegue con Docker Compose[6] resume la actualización en parar los contenedores y ejecutar docker compose up --pull always. Hoy esa orden te lleva a la v4 sin modo de transición, por tres cambios en el repositorio:

  • Etiqueta latest: desde el PR #15607[7], del 23 de julio, apunta a la línea v4. El 16 de septiembre, langfuse/langfuse:latest tenía el mismo resumen que 4.37.0 (sha256:06c0eaae…)
  • Etiqueta del compose: el docker-compose.yml de la rama principal usa :4, y el de la etiqueta v3.225.8[8] usa :3
  • Registro: desde el PR #16265[9], del 12 de agosto, las imágenes se descargan de docker.langfuse.com en vez de docker.io

Si haces git pull en tu copia del repositorio y arrancas, entras directamente en events_only: el SDK v2 queda rechazado y el relleno del histórico empieza solo, sin que hayas comprobado la doble escritura.

El registro nuevo me dio otro problema: en esta máquina, docker.langfuse.com no resolvía, porque el DNS de la red devolvía ::.

Con un resolvedor público, el nombre es un alias de langfuse.docker.reo.dev, y la portada de Reo.Dev[10] cita a un cliente que valora que su producto "shows which developers are pulling Docker images". Un filtro DNS que bloquee ese dominio rompe la descarga. El proxy autentica contra Docker Hub y sirve el mismo resumen, así que puedes cambiar el registro por docker.io y la imagen es idéntica.

Cómo he probado la migración

Monté el stack con los docker-compose.yml oficiales de las etiquetas v3.225.8 y v4.37.0, más un fichero de sobrescritura con versiones fijas y puertos propios. Todo corrió en un contenedor de desarrollo linux/arm64 con 18 núcleos y 121 GB de RAM. La máquina estaba compartida con otras cargas, y la carga media osciló entre 2 y 73 durante la prueba, así que los tiempos son orientativos.

Estas son las versiones:

  • Langfuse: v3.225.8, después v4.37.0 (web y worker)
  • ClickHouse: 25.8.33.6, después 26.4.5.143
  • Resto del stack: PostgreSQL 17, Redis 7 y la imagen de MinIO de Chainguard que trae el compose
  • Herramientas: Docker 29.5.2 y Docker Compose v2.40.3

Con el servidor en v3 generé 45 931 trazas y 137 762 observaciones. De ellas, 40 000 trazas salieron del SDK de Python 2.60.10, 3598 del 3.15.0 y 2318 del 4.15.3. Con los dos SDK basados en OpenTelemetry lancé 10 000 trazas cada uno, pero mi bucle no vaciaba la cola y el SDK descartó el resto sin avisar.

En ClickHouse, esos datos ocupaban 81,2 MiB en la base default. El volumen entero ocupaba 1,7 GB, porque los registros del sistema pesan más que los datos. Es un conjunto pequeño, así que los tiempos del relleno no representan una instalación con millones de trazas.

Paso 0: llega a la última v3 y revisa las migraciones

La v4 borra tablas que la v3 dejó de usar, y la guía exige que todas las migraciones en segundo plano de v3 hayan terminado antes. Si alguna quedó a medias, los datos que no llegó a copiar se pierden. Actualiza primero a la última v3 (la v3.225.8 cuando escribo esto) y fija la etiqueta completa en vez de :3.

La guía propone una consulta que "must return zero rows". En una v3.225.8 sana, con el worker informando de que no quedaban migraciones, me devolvió estas cinco:

20260701_v4_step_1_create_root_spans_from_traces
20260701_v4_step_2_rewrite_observations_to_pid_tid_sorting
20260701_v4_step_3_backfill_events_full_from_observations
20260701_v4_step_4_backfill_events_full_from_dataset_run_items
20260701_v4_step_5_drop_pid_tid_sorting_tables

Son los pasos del relleno de v4, que la v3 ya registra y deja dormidos. No bloquean nada, y la consulta que te sirve los excluye:

docker compose exec -T postgres psql -U postgres -c "
  SELECT name, failed_at, failed_reason
  FROM background_migrations
  WHERE finished_at IS NULL
    AND name NOT LIKE '20260701_v4_%';"

Tiene que devolver cero filas. En la instalación nueva de mi prueba devolvió diez, porque el worker arrancó antes de que la web creara las tablas y su tanda de migraciones falló con The table public.background_migrations does not exist. El worker solo lo intenta al arrancar: un docker compose restart langfuse-worker las completó en menos de un segundo.

Paso 1: sube ClickHouse a 26.4 sin tocar Langfuse

La v4 exige ClickHouse 25.12 como mínimo y recomienda la 26.4, además de PostgreSQL 15 y Redis 7.0 o superiores. La v3 funciona con ClickHouse 24.3 o posterior, según la página de ClickHouse de Langfuse[11], así que puedes subir ClickHouse con la v3 en marcha y quedarte así el tiempo que quieras. Fija la versión en un fichero de sobrescritura, junto al compose:

services:
  clickhouse:
    image: docker.io/clickhouse/clickhouse-server:26.4

Después recrea solo ese servicio con docker compose up -d clickhouse; Compose lee docker-compose.override.yml sin que se lo indiques. En mi prueba, ClickHouse pasó de 25.8.33.6 a 26.4.5.143 y volvió a estar sano en 7,4 s. La v3 siguió recibiendo datos: 20 trazas nuevas del SDK v2 aparecieron en la API, y el listado de trazas respondió en 0,18 s.

La guía añade una lista de permisos para el usuario de ClickHouse. Con el compose oficial no hace falta, porque el usuario que crea la imagen ya tenía ALTER, CREATE, DROP y SYSTEM sobre todas las bases, según SHOW GRANTS. Si usas un ClickHouse externo con un usuario restringido, concede esos permisos antes del paso 3.

Reserva también disco para el paso 5. La guía pide margen para "roughly 3x" el volumen actual de ClickHouse, y en mi prueba las tablas de trazas llegaron a 3,55 veces su tamaño antes de limpiar.

La trampa de la versión fijada en el compose de v4

No dejes que el compose nuevo baje la versión de ClickHouse. El de v3 usaba la imagen sin etiqueta, que el 16 de septiembre era la 26.8.5, y el de v4 fija la 25.12. Probé tres combinaciones sobre una copia de mis datos:

Datos abiertos antes por Arranque con Resultado
26.4 25.12 Arranca y lee las 45 931 trazas
26.8 26.4 Arranca
26.8 25.12 Se detiene con el código 210

El error aparece en las tablas de registro del sistema que la 26.8 había creado, no en las de Langfuse:

Code: 115. DB::Exception: Unknown setting 'table_readonly':
for storage MergeTree: Cannot attach table `system`.`text_log_1`

La documentación de ClickHouse sobre actualizaciones[12] avisa de que solo puedes volver a una versión anterior "if you have not started to use any of the new features". Si ya ejecutas la 26.8, fija la 26.8 en tu sobrescritura en vez de heredar la 25.12 del compose.

Paso 2: haz copia de PostgreSQL y ClickHouse

No hay vuelta automática a v3 una vez aplicadas las migraciones de v4, así que la copia va justo antes del cambio de servidor. Para PostgreSQL, un volcado es suficiente; en mi instalación ocupó 312 KB, porque ahí solo viven la configuración, los usuarios y los prompts:

docker compose exec -T postgres \
  pg_dump -U postgres -Fc postgres > langfuse-pg.dump

ClickHouse guarda las trazas. En una sola máquina, la forma más directa es parar la web, el worker y ClickHouse y empaquetar el volumen:

docker compose stop langfuse-web langfuse-worker clickhouse
docker run --rm -v langfuse_langfuse_clickhouse_data:/src:ro \
  -v "$PWD":/dst alpine \
  tar czf /dst/clickhouse-data.tgz -C /src .
docker compose start clickhouse

El nombre del volumen empieza por el nombre de tu proyecto de Compose; compruébalo con docker volume ls. Parar y empaquetar los 1,7 GB del volumen tardó 70,5 s y dejó un fichero de 934 MB. Guarda los dos ficheros fuera de la máquina, por ejemplo con restic y un repositorio cifrado.

Paso 3: arranca la v4 en modo de doble escritura

El modo dual escribe cada evento en las tablas viejas y en las nuevas, así que todo lo de v3 sigue funcionando mientras migras los clientes. Las variables de la migración no aparecen en el docker-compose.yml oficial, y Compose solo pasa al contenedor las variables que el fichero declara: si las pones en .env, no llegan. Añádelas a los dos servicios en la sobrescritura:

x-migracion-v4: &migracion-v4
  LANGFUSE_MIGRATION_V4_WRITE_MODE: dual
  LANGFUSE_MIGRATION_V4_NATIVE_OTEL_BEHAVIOUR: dual_write
  LANGFUSE_MIGRATION_V4_ALLOW_PREVIEW_OPT_IN: "false"
  LANGFUSE_BACKGROUND_MIGRATION_V4_ENABLE_HISTORIC_BACKFILL: "false"

services:
  langfuse-worker:
    image: docker.io/langfuse/langfuse-worker:4.37.0
    environment: *migracion-v4
  langfuse-web:
    image: docker.io/langfuse/langfuse:4.37.0
    environment: *migracion-v4
  clickhouse:
    image: docker.io/clickhouse/clickhouse-server:26.4

Cada variable controla una parte de la transición:

  • LANGFUSE_MIGRATION_V4_WRITE_MODE: dual escribe en las dos familias de tablas; legacy conserva el comportamiento completo de v3
  • LANGFUSE_MIGRATION_V4_NATIVE_OTEL_BEHAVIOUR: dual_write hace pasar las trazas de OpenTelemetry sin la cabecera de v4 por la tubería que copia los atributos de la traza
  • LANGFUSE_MIGRATION_V4_ALLOW_PREVIEW_OPT_IN: con false, todos siguen viendo la interfaz de v3 y la API v2 no responde
  • LANGFUSE_BACKGROUND_MIGRATION_V4_ENABLE_HISTORIC_BACKFILL: con false, el relleno espera a que tú lo actives

La última es la que más importa. El relleno se ejecuta una sola vez, y lo que entre entre su final y el inicio de la doble escritura no llega nunca a las tablas nuevas.

Con el compose nuevo y la sobrescritura, arranca con docker compose up -d. La web respondió {"status":"OK","version":"4.37.0"} a los 10,7 s. En ese tiempo aplicó 14 migraciones de PostgreSQL, entre ellas drop_legacy_tracing_tables, y 12 de ClickHouse, de la versión 38 a la 49.

Las 12 de ClickHouse crean events_full, events_core y la tabla de preparación observations_batch_staging, y borran event_log, project_environments y dataset_run_items. Con la vista previa desactivada, los endpoints de v3 seguían respondiendo 200, y GET /api/public/v2/observations devolvía 404 con el aviso "The observations v2 API is only available in a Langfuse v4 write mode".

Paso 4: comprueba la doble escritura con cada SDK

Cada generación del SDK llega a events_full por un camino distinto, y conviene verlo con tus datos antes de seguir. Envié 50 trazas con cada SDK y anoté cuándo aparecían en la tabla nueva y si las observaciones hijas llevaban usuario y sesión:

SDK de Python Tablas de v3 events_full Usuario en las hijas
2.60.10 Al instante A los 11 min Sí
3.15.0 sin dual_write Al instante Al instante No
3.15.0 con dual_write Al instante A los 8,5 min Sí
4.15.3 Al instante Al instante Sí

La segunda fila es la trampa. Sin LANGFUSE_MIGRATION_V4_NATIVE_OTEL_BEHAVIOUR, el valor por defecto es direct, y los spans del SDK v3 se escriben tal cual en events_full. Ese SDK solo pone usuario, sesión y etiquetas en el span raíz, así que las 100 observaciones hijas quedaron sin ellos, y un filtro por usuario en la vista nueva no las encuentra.

El relleno del paso 5 tampoco las corrigió. Con dual_write, las trazas del mismo SDK pasaron por la tabla de preparación y salieron completas, con una fila raíz virtual encima de cada una.

El retraso tiene una causa concreta. El trabajo de propagación se ejecuta cada minuto y solo procesa particiones con más de 10 minutos de antigüedad, según el valor por defecto de LANGFUSE_EXPERIMENT_EVENT_PROPAGATION_PARTITION_DELAY_MINUTES en el código de la v4.37.0. La guía habla de unos 15 minutos.

Para vigilar la propagación, el worker responde en su puerto 3030 a GET /api/health?failIfEventPropagationStuck=true, que devuelve 503 si el trabajo lleva demasiado tiempo sin ejecutarse. La guía dice que el umbral por defecto son 15 minutos, pero la v4.37.0 respondía "thresholdSeconds":2100 (35 minutos), y ese es el valor fijado en su código. Un comentario en ese código pide que la sonda espere al menos 60 s antes de la primera comprobación.

Paso 5: rellena el histórico

El relleno copia a events_full todo lo que entró antes de la doble escritura, y solo debes activarlo cuando el paso 4 esté verificado. Cambia LANGFUSE_BACKGROUND_MIGRATION_V4_ENABLE_HISTORIC_BACKFILL a "true" y vuelve a ejecutar docker compose up -d. El worker encadena cuatro migraciones en segundo plano:

  1. Crea una observación raíz virtual por cada traza, con el identificador t- seguido del de la traza
  2. Reescribe las observaciones en una tabla intermedia, observations_pid_tid_sorting, ordenada para la unión siguiente
  3. Une esa tabla con las trazas y escribe las observaciones hijas en events_full
  4. Añade los metadatos de experimentos a los spans que los necesitan

Con mis 45 931 trazas, la cadena tardó 3 min 5 s, de las 16:11:57 a las 16:15:02 UTC. Cada paso terminó casi al minuto exacto del anterior, así que ese tiempo mide la cadencia del worker. La copia en sí fue más breve: los datos del paso 1 ya estaban en disco a los 7 s.

Al final, events_full tenía 185 623 filas, 46 201 de ellas raíces virtuales. Las 120 000 observaciones del SDK v2 recibieron usuario y sesión, pero los metadatos de la traza se quedaron solo en la raíz virtual, como la guía advierte.

El disco es lo que tienes que vigilar:

Momento Tamaño en ClickHouse
Tablas traces y observations antes del relleno 49,9 MiB
Tablas nuevas events_full y events_core 93,8 MiB
Tabla intermedia observations_pid_tid_sorting 33,1 MiB
Base default antes y en el pico 82,3 MiB y 208,6 MiB

Sumando tablas viejas, nuevas e intermedia, las trazas pasaron de ocupar 49,9 MiB a 176,8 MiB, 3,55 veces su tamaño inicial, algo por encima del "roughly 3x" de la guía. Los datos sintéticos se comprimen distinto que los reales, así que toma la proporción como propia de estos datos y deja más margen del que pide la guía.

Paso 6: pasa a events_only

El corte es el punto sin retorno: a partir de aquí, los datos nuevos solo se escriben en las tablas de v4. Antes, migra todo lo que envía datos a Langfuse o los lee:

  • Productores: el SDK de Python a la 4.7.0 o superior, donde update_current_trace() pasa a ser propagate_attributes() según la guía de migración del SDK[13]
  • Lectores de la API: a Observations API v2, Metrics API v2 y Scores API v3
  • Evaluadores: de la traza a la observación
  • Exportaciones: a la fuente "Enriched observations"

Después, quita las variables LANGFUSE_MIGRATION_V4_* de la sobrescritura y vuelve a ejecutar docker compose up -d. La web y el worker estuvieron de vuelta en 17,9 s.

Esto es lo que vi justo después del corte, con 20 trazas por SDK:

  • SDK de Python 2.60.10: imprimió 140 veces "Bad request. Please check your request for any missing or incorrect parameters", una por evento, y terminó con código 0. No se guardó nada
  • SDK de Python 3.15.0: se guardó, pero las observaciones hijas volvieron a quedar sin las etiquetas de la traza
  • SDK de Python 4.15.3: se guardó completo
  • GET /api/public/traces, observations, sessions y metrics/daily: 404, con el mensaje "This endpoint is not available on deployments running in Langfuse v4 events_only mode"
  • POST /api/public/ingestion: 207, con 201 para el score-create y 400 para el trace-create
  • GET /api/public/v2/observations?traceId=…: 200 en 16 ms, con las cuatro filas de una traza antigua del SDK v2 (la raíz virtual y sus tres hijas)

La respuesta 400 del servidor explica el problema y hasta propone volver a dual como puente, pero el SDK v2 no muestra ese texto. Si una aplicación antigua se te escapa, lo único que verás son esas líneas genéricas en su registro, sin fallo del proceso. Revisa los registros de cada productor tras el corte.

La combinación de variables también se valida, aunque en mi prueba solo lo hizo el worker. Con events_only y LANGFUSE_MIGRATION_V4_ALLOW_PREVIEW_OPT_IN=false, el worker salió con código 1 y el mensaje Invalid V4 config: LANGFUSE_MIGRATION_V4_WRITE_MODE=events_only requires LANGFUSE_MIGRATION_V4_ALLOW_PREVIEW_OPT_IN=true, mientras la web arrancaba sin quejarse.

Vista de trazas de Langfuse v4.37.0 tras la migración, filtrada por observaciones raíz: 46 000 trazas raíz y 139 000 observaciones hijas del conjunto de prueba, con las columnas de entrada y salida del agente de soporte.

Tras el corte, la vista de trazas abre filtrada por isRootObservation:true, que en mi instalación mostraba 46 000 raíces frente a 139 000 observaciones hijas.

Cómo volver a v3 si algo falla

Mientras sigas en dual o legacy, puedes volver a v3 sin restaurar la copia, aunque no basta con cambiar la etiqueta de la imagen. Lo probé con la v4 en dual: la web de v3.225.8 entró en bucle de reinicios con error: no migration found for version 49. La guía cita la versión 46; el número es el de la última migración de ClickHouse que aplicó tu v4, así que variará.

El arreglo es rebobinar el esquema de ClickHouse con el binario migrate que trae la imagen web de v4, desde un contenedor de la misma versión que tienes desplegada:

docker compose exec langfuse-web sh -c '
cd /app/packages/shared && migrate \
  -source file://clickhouse/migrations/unclustered \
  -database "${CLICKHOUSE_MIGRATION_URL}?username=${CLICKHOUSE_USER}\
&password=${CLICKHOUSE_PASSWORD}&database=default\
&x-multi-statement=true&x-migrations-table-engine=MergeTree" \
  goto 37'

La orden deshizo las 12 migraciones en 2,4 s: borró las tablas de v4 y recreó event_log, project_environments y dataset_run_items. Con las imágenes de v3.225.8, la web arrancó en 16,7 s sobre el esquema de PostgreSQL de v4, mostró las 46 201 trazas y volvió a aceptar el SDK v2.

Lo hice después del corte, a propósito, para ver qué se pierde. Las trazas enviadas en modo dual estaban todas; las 20 enviadas con el SDK v4 después del corte no aparecían, porque solo existían en events_full. Por eso el corte es el punto de compromiso, y a partir de ahí la única vuelta atrás es la copia del paso 2.

Cuánto disco recuperas al terminar

La limpieza tiene dos partes, y las dos son opcionales. La primera es la tabla intermedia: con LANGFUSE_BACKGROUND_MIGRATION_V4_DROP_PID_TID_SORTING_TABLES a "true", el worker la borró al arrancar, y la base bajó de 208,6 a 175,7 MiB.

La segunda son las tablas traces y observations, que tras el corte ya no reciben escrituras ni lecturas. La guía pide vaciarlas con TRUNCATE TABLE en vez de borrarlas, porque Langfuse espera que existan. En mi caso liberaría otros 49,9 MiB, pero también eliminaría la única fuente para repetir el relleno y la vuelta a v3 del apartado anterior. Déjalas unas semanas y vacíalas cuando hayas comprobado el histórico en la vista nueva.

Preguntas frecuentes

¿Puedo quedarme en Langfuse v3?

Hasta final de enero de 2027, con parches de seguridad y sin funciones nuevas. Si además usas Langfuse Cloud, esa parte pasa a ser solo v4 el 16 de noviembre de 2026, así que tus SDK tendrán que estar actualizados antes de esa fecha de todas formas.

¿Puedo actualizar los SDK antes que el servidor?

Sí. El SDK de Python 4.15.3 envió trazas a mi servidor v3.225.8 sin errores, y la guía confirma que Python v4 y JS/TS v5 funcionan con servidores v3. La excepción son langfuse.api.observations y langfuse.api.metrics, que en el SDK v4 apuntan a las API v2; contra un servidor v3 usa langfuse.api.legacy.observations_v1.

¿Cuánto disco necesita el relleno del histórico?

En mi prueba, las tablas de trazas llegaron a 3,55 veces su tamaño inicial antes de borrar la tabla intermedia, y a 2,88 veces después. Calcula el margen sobre el tamaño de traces y observations en system.parts, no sobre el volumen entero de ClickHouse, que incluye los registros del sistema.

Conclusión

Migrar Langfuse de v3 a v4 lleva seis pasos, y ninguno exige parar el servicio más de un minuto, salvo la copia del volumen. Los riesgos están en lo que la documentación no dice. El compose y la etiqueta latest ya apuntan a v4, y el compose nuevo puede bajarte ClickHouse de versión. Además, las trazas del SDK v3 pierden sus atributos si no activas dual_write desde el principio.

Mi recomendación es fijar versiones, pasar un par de días en dual revisando qué productores siguen con SDK antiguos y cortar solo cuando los registros de todos estén limpios. Con la v4 funcionando, repasa qué instrumentar primero en tus agentes para sacar partido a las observaciones por fila.

La versión en inglés de esta guía está en How to migrate self-hosted Langfuse from v3 to v4.

Fuentes

  1. artículo técnico de Langfuse
  2. Langfuse v4.0.0
  3. anuncio de la versión 4
  4. guía oficial de migración
  5. matriz de compatibilidad
  6. guía de despliegue con Docker Compose
  7. PR #15607
  8. etiqueta v3.225.8
  9. PR #16265
  10. Reo.Dev
  11. página de ClickHouse de Langfuse
  12. documentación de ClickHouse sobre actualizaciones
  13. guía de migración del SDK