SSD Nodes Learn Hosting plans →
Guides Matt ConnorPar Matt Connor · Mis à jour le 2026-08-27

Auto-héberger Langfuse pour tracer vos agents IA

Déployez Langfuse sur votre VPS avec le minimum de ressources, des images versionnées, TLS, une rétention ClickHouse maîtrisée et des sauvegardes testées.

Pourquoi tracer un agent IA

Vous auto-hébergez Langfuse pour voir ce que votre agent a réellement fait lors d’une exécution. Langfuse est un outil open source d’observabilité des LLM (large language models). Il enregistre chaque prompt, chaque réponse du modèle, chaque appel d’outil et chaque token, puis les regroupe dans une trace que vous pouvez ouvrir et consulter. En l’exécutant sur votre propre VPS, ces prompts ne quittent jamais un serveur que vous contrôlez.

La raison est simple. Vous ne pouvez pas corriger un problème de coût ou de qualité que vous ne voyez pas. Une facture fournisseur vous indique que mardi a coûté quatre fois plus cher que lundi. Une trace vous indique quelle exécution de l’agent en est responsable, quel prompt est passé à 40,000 tokens et quelle boucle de retry a été exécutée neuf fois avant d’abandonner. La facture donne le chiffre. La trace montre le code qui l’a produit.

Trois termes sont utilisés dans ce guide. Une trace est une exécution complète de votre agent, du début à la fin. Une observation est une étape de cette exécution : un span pour du code ordinaire, une generation pour un appel à un modèle. Un score est un nombre associé à une trace, provenant d’une évaluation humaine ou automatisée. Langfuse utilise OpenTelemetry (OTel), le standard indépendant des fournisseurs pour le distributed tracing. L’instrumentation dont vous disposez déjà peut donc pointer vers Langfuse.

Ce que l’auto-hébergement de Langfuse exécute réellement

Langfuse v4 ne tient pas dans un seul conteneur. Il utilise deux conteneurs applicatifs et quatre services de stockage. Sur un VPS unique, les six s’exécutent sur votre serveur.

  • langfuse-web fournit l’interface web et l’API d’ingestion.
  • langfuse-worker traite la file d’attente en arrière-plan. Il analyse les lots d’ingestion, calcule les coûts et exécute la tâche de rétention nocturne.
  • Postgres stocke les données transactionnelles, comme les utilisateurs, les organisations, les projets, les clés API et les prompts.
  • ClickHouse stocke les données de trace elles-mêmes, c’est-à-dire les observations et les scores. Il s’agit d’un column store conçu pour les requêtes analytiques. C’est pourquoi un dashboard portant sur plus de cent millions de lignes répond encore rapidement.
  • Redis est la file d’attente et le cache situés entre le web et le worker.
  • MinIO fournit un stockage objet compatible S3 sur le serveur. Il stocke chaque événement brut entrant ainsi que tous les médias que vous lui associez.

Langfuse publie les ressources minimales nécessaires pour les trois composants qui effectuent le traitement.

ChartLangfuse published minimum resources per component
The data behind this chart
[
  {
    "label": "ClickHouse",
    "cpu_cores": 2,
    "memory_gib": 8
  },
  {
    "label": "Langfuse web",
    "cpu_cores": 2,
    "memory_gib": 4
  },
  {
    "label": "Langfuse worker",
    "cpu_cores": 2,
    "memory_gib": 4
  }
]

ClickHouse demande à lui seul 8 Gio de mémoire. Le conteneur web et le worker demandent chacun 4 Gio. Ce sont les minimums publiés pour les 3 composants dimensionnés par Langfuse. Postgres, Redis et MinIO ont encore besoin de mémoire en plus. Le guide Docker Compose du projet recommande une machine avec 4 cœurs, 16 Gio de mémoire et environ 100 Gio de stockage. Cela correspond à ce calcul, sans marge artificielle.

N’essayez pas cette installation avec une offre de 2 Gio. ClickHouse démarre et accepte des écritures pendant un certain temps, puis s’arrête lors d’un merge en arrière-plan, car un merge charge de grandes parties d’une table en mémoire. Vous verrez docker compose ps signaler que le conteneur clickhouse est restarting, dmesg afficher une ligne comme Out of memory: Killed process 1234 (clickhouse-serv), et tous les dashboards Langfuse renvoyer une erreur 500. Avec une charge moindre, ClickHouse refuse plutôt la requête et journalise DB::Exception: Memory limit (total) exceeded. Huit Gio peuvent convenir à un seul développeur qui envoie quelques milliers de traces par jour. Prévoyez 16 Gio. Si le même VPS doit héberger autre chose, prévoyez ses ressources séparément, car même une stack relativement légère comme un espace de travail AFFiNE auto-hébergé nécessite ses propres gigaoctets, et ClickHouse ne vous en restituera aucun.

Déployer Langfuse avec Docker Compose

Clonez le dépôt. La stack, son câblage et l’environnement par défaut se trouvent dans son docker-compose.yml.

git clone https://github.com/langfuse/langfuse.git
cd langfuse

Toutes les valeurs à modifier sont marquées # CHANGEME dans ce fichier. Générez d’abord les trois secrets de l’application.

openssl rand -base64 32   # NEXTAUTH_SECRET
openssl rand -base64 32   # SALT
openssl rand -hex 32      # ENCRYPTION_KEY

ENCRYPTION_KEY doit faire 256 bits et être écrit sous la forme de 64 caractères hexadécimaux, ce que openssl rand -hex 32 affiche exactement. Il chiffre les valeurs sensibles au repos, notamment les clés des fournisseurs LLM que vous stockez dans l’instance. Si vous le modifiez après la création des données, ces lignes ne pourront plus être déchiffrées. Considérez-le donc comme définitif dès le premier démarrage. SALT sert à hacher vos clés API Langfuse. Le modifier invalide donc toutes les clés déjà utilisées par vos agents.

Définissez ensuite POSTGRES_PASSWORD, CLICKHOUSE_PASSWORD, REDIS_AUTH et MINIO_ROOT_PASSWORD. Le mot de passe MinIO apparaît à quatre endroits : une fois comme MINIO_ROOT_PASSWORD, puis de nouveau comme LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY, LANGFUSE_S3_MEDIA_UPLOAD_SECRET_ACCESS_KEY et LANGFUSE_S3_BATCH_EXPORT_SECRET_ACCESS_KEY. Si vous en oubliez un, MinIO rejette ce client avec SignatureDoesNotMatch. Le message apparaît dans le journal du worker, alors que l’interface web semble toujours fonctionner. Conserver ces valeurs dans un fichier env plutôt que dans le fichier compose suivi par Git est la méthode présentée dans Fichiers env et secrets Docker Compose.

Figez les tags des images avant de commencer

Le fichier fourni utilise langfuse/langfuse:4 et langfuse/langfuse-worker:4. Ces tags évoluent. Langfuse exécute automatiquement les migrations Postgres et ClickHouse au démarrage. Ainsi, un docker compose pull ordinaire quelques mois plus tard devient une migration de schéma imprévue sur une base de données qui n’a pas été sauvegardée ce matin-là. Figez les deux images sur une même version dans un docker-compose.override.yml. Compose le fusionne par-dessus le fichier fourni, afin qu’un prochain git pull ne remplace pas vos modifications.

services:
  langfuse-web:
    image: docker.io/langfuse/langfuse:4.3.1
  langfuse-worker:
    image: docker.io/langfuse/langfuse-worker:4.3.1

La version 4.3.1 était la version 4.3 actuelle en août 2026 (la version 4.4.0 est sortie depuis). Consultez la page des releases GitHub du projet, figez la version actuelle le jour du déploiement, puis faites évoluer ce numéro volontairement. Les images de stockage du fichier fourni sont déjà limitées à des versions majeures, postgres:17, clickhouse-server:25.12 et redis:7. Elles doivent suivre la même règle. Cette règle ne concerne pas uniquement Langfuse : un tracker auto-hébergé d’entraînements openGym utilise une fraction de cette stack et nécessite malgré tout un tag git nommé, car tout service qui migre sa propre base de données au démarrage peut transformer un pull ordinaire en modification de schéma.

Démarrez la stack.

docker compose up -d
docker compose ps
docker compose logs -f langfuse-worker

Le premier démarrage exécute les migrations. Attendez donc une ou deux minutes avant d’obtenir une réponse. docker compose ps doit afficher six services dans l’état running. Si le worker redémarre en boucle, son journal en indique la cause : CLICKHOUSE_MIGRATION_URL utilise le protocole natif ClickHouse sur le port 9000, et non le port HTTP 8123. Le pointer vers 8123 échoue à cet endroit, alors que le conteneur web semble toujours fonctionner.

Vérifiez l’état depuis le serveur lui-même.

curl -s "http://localhost:3000/api/public/health?failIfDatabaseUnavailable=true"
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:3000/api/public/ready

Un appel /api/public/health simple prouve uniquement que le processus API est actif. Il ignore volontairement la base de données afin que le service continue à répondre pendant une interruption de Postgres. La forme failIfDatabaseUnavailable=true est celle qu’il faut utiliser avec un outil de monitoring. Elle renvoie 503 lorsque la base de données est inaccessible. /api/public/ready renvoie 200 une fois les migrations terminées et le conteneur prêt à accepter du trafic. Il s’agit dans les deux cas de vérifications HTTP standard. Une page d’état Uptime Kuma peut donc les surveiller et vous signaler l’arrêt de la stack avant vos agents.

Placez TLS en frontal et fermez les ports supplémentaires

Le fichier Compose fourni publie 3000:3000 pour le conteneur web et 9090:9000 pour MinIO. Les deux services écoutent sur toutes les interfaces. Avec une IP publique, toute personne qui scanne le port 3000 accède à votre page d’inscription, et toute personne qui scanne le port 9090 accède au bucket contenant vos prompts bruts.

Une règle de pare-feu ne suffit pas à les fermer. Docker écrit ses propres règles DNAT dans la table nat. Ces règles sont évaluées avant que les règles de filtrage d’ufw ne voient le paquet. Ainsi, ufw deny 3000 laisse le port publié ouvert. Ce problème est suffisamment fréquent pour faire l’objet d’un guide dédié : pourquoi les ports publiés par Docker contournent ufw. Dans votre fichier override, liez plutôt les ports à l’interface loopback.

services:
  langfuse-web:
    ports:
      - "127.0.0.1:3000:3000"
    environment:
      NEXTAUTH_URL: https://langfuse.example.com
  minio:
    ports:
      - "127.0.0.1:9090:9000"
      - "127.0.0.1:9091:9001"

NEXTAUTH_URL doit être l’adresse publique exacte, schéma inclus, car le flux de connexion construit son URL de callback à partir de cette valeur. Si vous laissez http://localhost:3000 derrière un proxy HTTPS, l’aller-retour de connexion redirige le navigateur vers une adresse qu’il ne peut pas atteindre.

Configurez maintenant un reverse proxy vers 127.0.0.1:3000 et laissez-le gérer le certificat. Traefik dans le même projet Compose est le choix habituel, et les labels de routage sont ceux décrits dans exécuter plusieurs applications derrière un reverse proxy Traefik. Caddy fait le même travail en deux lignes si Langfuse est le seul service sur le serveur. Vérifiez avec curl -sI https://langfuse.example.com/api/public/ready, puis confirmez depuis une deuxième machine que curl http://YOUR_IP:3000 expire désormais sans réponse.

MinIO présente toutefois une particularité. Langfuse sert les médias associés à votre navigateur au moyen d’URL presignées qui pointent vers cet endpoint S3. Si vous utilisez des traces multimodales contenant des images ou de l’audio, un MinIO limité à loopback empêchera le chargement de ces pièces jointes. Consultez la page de configuration du blob storage avant de le placer derrière un proxy, car l’endpoint écrit dans l’URL presignée doit correspondre à l’adresse publiée. Les traces en texte brut ne sont pas concernées.

Créez votre compte lors de la première visite, puis gardez le contrôle de l’instance. Définissez LANGFUSE_ALLOWED_ORGANIZATION_CREATORS avec votre propre adresse e-mail, afin qu’une personne étrangère qui atteint la page ne puisse pas créer d’organisation sur votre serveur. Si vous utilisez déjà Authentik comme fournisseur d’identité, Langfuse accepte une connexion OIDC standard. Les comptes suivent alors le cycle de vie de vos autres applications, au lieu d’être stockés dans une liste de mots de passe connue uniquement de ce serveur.

Envoyez votre première trace

Créez un projet dans l’interface web, puis copiez ses clés publique et secrète depuis les paramètres du projet. Le SDK Python lit trois variables d’environnement.

export LANGFUSE_PUBLIC_KEY="pk-lf-..."
export LANGFUSE_SECRET_KEY="sk-lf-..."
export LANGFUSE_BASE_URL="https://langfuse.example.com"

LANGFUSE_BASE_URL est le nom de variable utilisé par le SDK v4, publié en mars 2026. Les anciens codes et les anciens guides utilisent LANGFUSE_HOST. Si vos traces arrivent sur Langfuse Cloud au lieu de votre serveur, cela vient d’une URL de base non définie : la valeur par défaut pointe vers l’instance hébergée.

pip install langfuse opentelemetry-instrumentation-anthropic anthropic
import os
from anthropic import Anthropic
from langfuse import get_client, observe
from opentelemetry.instrumentation.anthropic import AnthropicInstrumentor

AnthropicInstrumentor().instrument()
langfuse = get_client()
client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])

@observe(as_type="tool")
def lookup_order(order_id: str) -> str:
    return f"order {order_id}: shipped"

@observe()
def handle_request(question: str) -> str:
    context = lookup_order("A-1042")
    message = client.messages.create(
        model="claude-haiku-4-5",
        max_tokens=512,
        messages=[{"role": "user", "content": f"{context}\n\n{question}"}],
    )
    return message.content[0].text

if __name__ == "__main__":
    assert langfuse.auth_check()
    print(handle_request("Where is my order?"))
    langfuse.flush()

Le décorateur @observe ouvre une observation autour de la fonction, capture ses arguments et sa valeur de retour, puis l’imbrique dans l’observation déjà active, le cas échéant. AnthropicInstrumentor assure l’instrumentation OpenTelemetry du client Anthropic. Il transforme chaque appel messages.create en une génération contenant le nom du modèle, l’utilisation des tokens et la latence, sans modification du point d’appel.

Deux appels effectuent les vérifications à votre place. langfuse.auth_check() renvoie False si les clés sont incorrectes ou si l’URL de base est erronée. C’est plus rapide que de chercher pourquoi le tableau de bord reste vide. langfuse.flush() bloque jusqu’à l’envoi des spans en attente. Cette fonction est nécessaire pour les processus de courte durée, car le SDK regroupe les données en arrière-plan et un script qui se termine immédiatement emporte avec lui son lot non envoyé. Si toute une équipe envoie des traces plutôt qu’un seul script, définissez ces trois variables une seule fois dans la gateway que les agents utilisent déjà, au lieu de les définir dans le shell de chaque personne. C’est ainsi que un harness OneCLI auto-hébergé conserve l’instrumentation des exécutions de chaque collègue, tout en gardant les clés au même endroit.

Pourquoi ClickHouse continue-t-il de grossir ?

Les traces sont généralement les données qui croissent le plus vite dans un environnement auto-hébergé. Chaque exécution d’agent écrit une ligne par étape, et les entrées comme les sorties sont stockées intégralement. Un agent bavard avec de longs prompts produit donc bien plus d’octets par jour que l’application qu’il surveille. Si vous ne faites rien, ClickHouse remplit le disque. Un disque plein bloque l’ingestion au lieu de simplement la ralentir.

Deux éléments distincts grossissent ici. Ils nécessitent donc deux corrections distinctes.

Le premier est vos propres données de trace. La correction consiste à configurer la rétention. Ouvrez les paramètres du projet dans l’interface web et définissez une durée de rétention en jours. Langfuse accepte un minimum de 3 jours. Une tâche nocturne sélectionne ensuite les traces, observations, scores et médias plus anciens que cette durée, puis les supprime de ClickHouse et du blob storage. Cette tâche a besoin de l’autorisation DeleteObject sur le bucket. Les identifiants root de MinIO présents dans le fichier compose par défaut disposent déjà de cette autorisation. La suppression est définitive. Configurez donc d’abord un export vers le blob storage si vous devez conserver un historique à long terme. N’écrivez pas vous-même de clauses TTL sur les tables gérées par Langfuse. La tâche de rétention garantit la cohérence entre ClickHouse et le bucket. Un TTL manuel ne supprimerait les données que d’un seul côté.

Choisissez la durée en fonction de votre usage réel. Les contrôles de coût et de qualité portent sur des données datant de quelques jours, pas de plusieurs mois. Trente jours constituent un bon point de départ pour une petite équipe. Quatorze jours suffisent si vous n’ouvrez une trace que lorsqu’un problème survient.

Le second élément concerne les propres tables de journaux système de ClickHouse. Ce point surprend souvent, car le disque continue de se remplir après la configuration de la rétention. ClickHouse écrit trace_log, text_log, opentelemetry_span_log, metric_log et asynchronous_metric_log pour ses diagnostics. Ces tables sont livrées sans TTL, et Langfuse ne les lit jamais. Commencez par déterminer où l’espace disque a réellement été utilisé.

SELECT table, formatReadableSize(size) AS size, rows FROM (
    SELECT table, database, sum(bytes) AS size, sum(rows) AS rows
    FROM system.parts
    WHERE active
    GROUP BY table, database
    ORDER BY size DESC
)

Exécutez cette commande avec docker compose exec clickhouse clickhouse-client --password "$CLICKHOUSE_PASSWORD". Si les tables système figurent parmi les plus volumineuses, désactivez-les avec un config overlay, car ClickHouse fusionne au démarrage chaque fichier de /etc/clickhouse-server/config.d/ avec sa configuration principale.

<clickhouse>
    <trace_log remove="1"/>
    <text_log remove="1"/>
    <opentelemetry_span_log remove="1"/>
    <asynchronous_metric_log remove="1"/>
    <metric_log remove="1"/>
</clickhouse>

Montez-le, puis redémarrez ClickHouse.

services:
  clickhouse:
    volumes:
      - ./clickhouse-config.d/system-logs.xml:/etc/clickhouse-server/config.d/system-logs.xml:ro

Cela arrête les nouvelles écritures. Les lignes déjà présentes sur le disque y restent. Récupérez donc explicitement l’espace avec DROP TABLE IF EXISTS system.trace_log, puis procédez de même pour chaque table supprimée. Si vous préférez conserver les diagnostics, l’autre solution consiste à appliquer un TTL agressif à chaque table au lieu d’utiliser remove="1". La documentation de Langfuse sur le scaling décrit cette méthode.

Une autre table mérite votre attention. blob_storage_file_log suit les fichiers d’événements envoyés vers votre bucket. Si vous configurez également une lifecycle policy sur le bucket, définissez un TTL correspondant sur cette table afin d’éviter tout décalage entre les deux.

ALTER TABLE blob_storage_file_log MODIFY TTL created_at + INTERVAL 30 DAY DELETE;

Ajoutez également une alerte simple df -h sur le disque de données. Les traces ne croissent pas régulièrement. Elles augmentent fortement le jour où vous déployez un nouvel agent. Le premier signe de cette hausse ne doit pas être une ingestion qui échoue.

Sauvegarder Postgres et ClickHouse

Une sauvegarde de Langfuse comporte trois éléments. Postgres contient vos utilisateurs, organisations, projets et clés d’API. ClickHouse contient les traces. MinIO contient les événements bruts. Si vous restaurez uniquement Postgres, vous obtenez une connexion fonctionnelle, mais aucun historique. Si vous restaurez uniquement ClickHouse, vous obtenez un historique auquel personne ne peut accéder. Cette séparation n’est pas propre à Langfuse. Un centre de support Chatwoot auto-hébergé présente la même structure : si le dump Postgres est réalisé sans le répertoire des uploads, les conversations sont restaurées, mais toutes leurs pièces jointes ont disparu.

Postgres est un simple pg_dump, conformément aux recommandations de la documentation de sauvegarde de Langfuse.

docker compose exec -T postgres pg_dump -U postgres postgres \
  | gzip > langfuse-pg-$(date +%F).sql.gz

ClickHouse demande davantage de précautions, car la copie d’un répertoire de données actif pendant l’exécution de merges ne produit pas une sauvegarde cohérente. Sur une machine unique, la méthode simple consiste à arrêter le conteneur, puis à archiver le volume.

docker compose stop clickhouse
docker volume ls | grep clickhouse
docker run --rm -v langfuse_langfuse_clickhouse_data:/data -v "$PWD":/backup alpine \
  tar czf /backup/langfuse-ch-$(date +%F).tar.gz -C /data .
docker compose start clickhouse

Utilisez le nom du volume affiché par docker volume ls, et non celui écrit dans le fichier YAML. Le fichier déclare langfuse_clickhouse_data, puis Compose lui ajoute le nom du projet. Ainsi, un clone dans un répertoire appelé langfuse produit langfuse_langfuse_clickhouse_data. Si vous vous trompez, docker run crée un nouveau volume vide sans afficher d’erreur, et votre archive ne contient rien.

Le conteneur web écrit chaque événement entrant dans le bucket avant son traitement par le worker. Un court arrêt de ClickHouse signifie donc généralement que le worker réessaie ensuite. Effectuez cette opération pendant une période creuse et réduisez sa durée. Pour une instance plus sollicitée, l’instruction BACKUP DATABASE default TO S3(...) de ClickHouse crée une sauvegarde cohérente sans arrêter le serveur. MinIO constitue le troisième élément. mc mirror ou la réplication MinIO vers un bucket externe permet de le sauvegarder. Quel que soit le format produit, copiez-le hors du serveur : c’est le rôle des sauvegardes restic chiffrées sur un VPS.

Redis n’a pas besoin d’être sauvegardé. Il contient la queue et le cache. Sa perte vous fait uniquement perdre les événements en cours de traitement, pas les événements plus anciens.

La limite liée à la cohérence est réelle et doit être énoncée clairement. Postgres et ClickHouse sont sauvegardés à des moments différents. Une restauration peut donc laisser une ligne de projet sans traces, ou des traces associées à un projet qui n’existe plus. Langfuse tolère cette situation, mais effectuez les deux dumps à peu d’intervalle et pendant une période de faible trafic. Le bucket d’événements constitue la véritable protection, car Langfuse y persiste chaque événement entrant avant de le traiter.

Restaurez au moins une fois dans une stack de test. Vous détecterez ainsi immédiatement un nom de volume incorrect, au lieu de le découvrir pendant une panne.

Ce qu’il faut examiner en premier

Quatre éléments méritent votre attention dès la première semaine.

  • Coût par trace. Langfuse calcule le coût à partir du nom du modèle et de l’utilisation des tokens. Triez donc les traces par coût, puis lisez entièrement la plus chère. Il s’agit généralement d’un prompt qui a grandi : un document entier collé dans le contexte ou un historique de conversation que personne ne tronque. Une fois ce phénomène visible, maîtriser le coût d’un agent IA devient une tâche d’ingénierie plutôt qu’une estimation.
  • Répartition des tokens entre l’entrée et la sortie. Les tokens d’entrée sont nombreux et peu coûteux. Les tokens de sortie sont moins nombreux et plus coûteux. Les tokens d’entrée mis en cache coûtent encore moins cher. Le même calcul est détaillé dans le décompte des tokens utilisés par Claude Code, et il s’applique à tout agent que vous écrivez vous-même.
  • Percentiles de latence. La médiane masque le problème. Les p95 et p99 concentrent les timeouts. Dans une boucle d’agent, un appel d’outil lent au p95 voit son impact multiplié par le nombre d’itérations.
  • Appels d’outils en échec. Filtrez les observations par niveau ERROR. Un outil qui échoue 5% du temps ne se voit pas dans un taux de réussite global. En revanche, il est très visible dans les traces, où vous pouvez observer le modèle réessayer, puis consommer des tokens pour contourner le problème.

Définissez la durée de rétention et choisissez le dashboard que vous consulterez chaque semaine, le même jour que votre déploiement. Un outil d’observabilité que personne n’ouvre est une base de données qui finit par remplir un disque.

FAQ

De quelle quantité de mémoire Langfuse auto-hébergé a-t-il besoin ?

Prévoyez 4 cœurs CPU et 16 GiB de mémoire. C’est la configuration recommandée par le guide Langfuse Docker Compose pour une seule machine virtuelle. Prévoyez également environ 100 GiB de stockage. Les minimums publiés pour les composants sont de 8 GiB pour ClickHouse et de 4 GiB chacun pour les conteneurs web et worker. Postgres, Redis et MinIO ont aussi besoin de mémoire en plus. Huit GiB suffisent pour l’instance d’un seul développeur. Deux GiB ne suffisent pas : le noyau tue ClickHouse pendant les merges en arrière-plan, et dmesg affiche Out of memory: Killed process.

Pourquoi le disque de ClickHouse continue-t-il de se remplir après la configuration de la rétention des données ?

Le paramètre de rétention couvre uniquement les données propres à Langfuse. ClickHouse écrit séparément dans ses tables de diagnostic trace_log, text_log, opentelemetry_span_log, metric_log et asynchronous_metric_log, qui n’ont aucun TTL. Exécutez system.parts avec un regroupement par table pour identifier la table la plus volumineuse. Désactivez ensuite les tables inutilisées avec une entrée remove="1" dans un fichier situé sous /etc/clickhouse-server/config.d/, redémarrez ClickHouse, puis supprimez les tables existantes pour récupérer l’espace déjà utilisé.

Quelle est la durée minimale de rétention des données dans Langfuse ?

Trois jours. La rétention se configure par projet dans les paramètres du projet ou via l’API projects. Une tâche nocturne supprime les traces, les observations, les scores et les ressources multimédias plus anciennes que cette période dans ClickHouse et dans le stockage d’objets. La suppression est irréversible. Configurez donc d’abord un export vers le stockage d’objets si vous devez conserver un historique au-delà de cette période.

Dois-je sauvegarder Postgres et ClickHouse ?

Oui, car ils stockent des données différentes. Postgres stocke les utilisateurs, les organisations, les projets et les clés API. ClickHouse stocke les données des traces elles-mêmes. Une restauration de Postgres uniquement vous donne une instance à laquelle vous pouvez vous connecter, mais qui ne contient aucune donnée. Sauvegardez également le bucket MinIO, car il contient les événements bruts que Langfuse persiste à leur arrivée. C’est ce qui se rapproche le plus d’une source de vérité dans cette stack.

Puis-je connecter une configuration OpenTelemetry existante à Langfuse auto-hébergé ?

Oui. Langfuse v4 et ses SDK v4 reposent sur OpenTelemetry. Les instrumentations OTel pour Anthropic et OpenAI exportent directement vers Langfuse. En Python, exécutez pip install langfuse opentelemetry-instrumentation-anthropic, appelez AnthropicInstrumentor().instrument() une fois au démarrage, puis définissez LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY et LANGFUSE_BASE_URL avec votre propre hôte. Vérifiez le résultat avec langfuse.auth_check() avant de rechercher un tableau de bord manquant.