SSD Nodes Learn Hosting plans →
ガイド Matt Connor著者 Matt Connor

Langfuseをセルフホストする方法と必要なVPS構成

Langfuse v4をVPSで運用する手順です。実際のリソース下限、固定するイメージタグ、TLS、ディスクを圧迫する前のClickHouse保持期間、復元できるバックアップを確認します。

AI エージェントを追跡する理由

Langfuse をセルフホストすると、エージェントが実行時に実際に何をしたかを確認できます。Langfuse は、オープンソースの LLM(大規模言語モデル)可観測性ツールです。すべてのプロンプト、モデルの応答、ツール呼び出し、トークンを記録し、それらを 1 つのトレースにまとめて開いて確認できるようにします。自分で管理する VPS で実行すれば、これらのプロンプトが自分の管理下にあるサーバーの外部へ送信されることはありません。

手間をかける理由は明確です。確認できないコストの問題や品質の問題は修正できません。プロバイダーの請求書からは、火曜日のコストが月曜日の 4 倍だったことは分かります。トレースからは、どのエージェント実行が原因だったか、どのプロンプトが 40,000 トークンまで増えたか、どの再試行ループが 9 回実行されてから失敗したかが分かります。請求書が示すのは数値です。トレースが示すのは、その数値を生み出したコードです。

このガイドでは、3 つの用語を使用します。トレースは、エージェントの最初から最後までの 1 回の実行です。オブザベーションは、その実行内の 1 つのステップです。通常のコードには span、モデルの呼び出しには generation を使用します。スコアは、人によるレビューまたは自動評価によってトレースに付与される数値です。Langfuse は、分散トレーシング向けのベンダー中立な標準である OpenTelemetry(OTel)に対応しているため、すでに導入している計装から Langfuse に送信できます。

セルフホストする Langfuse の実際の構成

Langfuse v4 は 1 つのコンテナではありません。2 つのアプリケーションコンテナと 4 つのストレージサービスで構成され、1 台の VPS では 6 つすべてがサーバー上で動作します。

  • langfuse-web は Web インターフェースと取り込み API を提供します。
  • langfuse-worker はバックグラウンドでキューを処理します。取り込みバッチを解析し、コストを計算し、夜間の保持期間処理を実行します。
  • Postgres は、ユーザー、組織、プロジェクト、API キー、プロンプトなどのトランザクションデータを保持します。
  • ClickHouse は、オブザベーションやスコアなどのトレースデータ自体を保持します。分析クエリ向けに構築されたカラム型ストアのため、1 億行を超えるデータに対するダッシュボードでも高速に応答できます。
  • Redis は、web と worker の間に置かれるキューおよびキャッシュです。
  • MinIO は、サーバー上に S3 互換のオブジェクトストレージを提供します。受信したすべての生イベントと、添付したメディアを保持します。

Langfuse は、実行する各コンポーネントの最小リソースを公開しています。次の図は、そのうち処理を担う 3 つを示しています。

グラフLangfuse published minimum resources per component
このグラフのデータ
[
  {
    "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 だけで 8 GiB のメモリを必要とします。web コンテナと worker は、それぞれ 4 GiB を必要とします。これらは、図に示した 3 コンポーネントの公開されている最低値です。同じページでは、Postgres に 4 GiB、Redis または Valkey に 1.5 GiB、MinIO に 4 GiB を挙げています。そのため、6 つすべての最低値を合計すると 25.5 GiB になります。プロジェクト独自の Docker Compose ガイドでは、1 台のマシンに少なくとも 4 コア、16 GiB のメモリ、約 100 GiB のストレージを推奨しています。これはコンポーネントの最低値の合計を下回るため、16 GiB は共有 Compose サーバーに必要な最低限の容量であり、余裕を含む値ではないと考えてください。

2 GiB のプランでは実行しないでください。ClickHouse は起動してしばらく書き込みを受け付けますが、バックグラウンドマージ中に停止します。マージでは、テーブルの大きなパーツをメモリに読み込むためです。docker compose ps が clickhouse コンテナを restarting と報告し、dmesg に Out of memory: Killed process 1234 (clickhouse-serv) のような行が記録され、すべての Langfuse ダッシュボードが 500 を返す状態になります。負荷が比較的軽い場合は、ClickHouse が代わりにクエリを拒否し、DB::Exception: Memory limit (total) exceeded をログに記録します。計画時は 16 GiB を基準にしてください。同じ VPS でほかのサービスも動かす場合は、その分を別途見積もる必要があります。比較的軽量な構成である セルフホストした AFFiNE ワークスペース でも、専用の GiB 単位のメモリが必要であり、ClickHouse はメモリを融通してくれないためです。

Docker Compose で Langfuse をデプロイする

リポジトリを clone します。スタック、各サービスの接続設定、デフォルト環境はすべて docker-compose.yml にあります。

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

変更が必要な値には、すべてそのファイル内で # CHANGEME が付いています。最初に、3 つのアプリケーション Secret を生成します。

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

ENCRYPTION_KEY は 64 個の 16 進文字で表す 256 ビット値である必要があります。これは openssl rand -hex 32 が正確に出力する形式です。この値は、インスタンスに保存する LLM プロバイダーのキーなど、保存時の機密値を暗号化します。データが存在した後に変更すると、それらの行を復号できなくなります。そのため、初回起動時から永続的な値として扱ってください。SALT は Langfuse API キーのハッシュ化に使用されるため、変更するとエージェントがすでに使用しているすべてのキーが無効になります。

次に POSTGRES_PASSWORD、CLICKHOUSE_PASSWORD、REDIS_AUTH、MINIO_ROOT_PASSWORD を設定します。MinIO のパスワードは 4 か所に記載されています。最初は MINIO_ROOT_PASSWORD、続いて LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY、LANGFUSE_S3_MEDIA_UPLOAD_SECRET_ACCESS_KEY、LANGFUSE_S3_BATCH_EXPORT_SECRET_ACCESS_KEY です。1 か所でも漏れると、MinIO はそのクライアントを SignatureDoesNotMatch として拒否します。このエラーは worker のログに記録されますが、Web インターフェースは正常に見えます。これらの値を追跡対象の compose ファイルではなく env ファイルに保存する方法は、Docker Compose の env ファイルと Secret で説明しています。

開始前にイメージタグを固定する

配布されているファイルでは docker.langfuse.com/langfuse/langfuse:4 と docker.langfuse.com/langfuse/langfuse-worker:4 が使用されています。これらのタグは更新されます。Langfuse は起動時に Postgres と ClickHouse のマイグレーションを自動実行するため、数か月後の通常の docker compose pull が、当日バックアップしていないデータベースに対する予定外のスキーママイグレーションになります。両方を docker-compose.override.yml 内の 1 つのリリースに固定してください。Compose はこれを配布ファイルに上書き適用するため、後から git pull しても編集内容と競合しません。これらと同じイメージは Docker Hub に公開されており、以下の override はそこから取得します。

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

2026 年 8 月時点では、バージョン 4.3.1 が最新の 4.3 リリースでした。その後もリリースは速いペースで行われており、2026 年 10 月 11 日時点では GitHub の最新バージョンは v4.56.0 でした。上記の override では、2026 年 10 月 31 日時点で GitHub の最新だった v4.72.0 を使用しています。プロジェクトの GitHub のリリースページを確認し、デプロイ当日に最新のバージョンを固定してください。その後は、意図を持ってバージョン番号を更新します。配布ファイル内の一部のストレージイメージにも同じ対応が必要です。これらのタグも更新されるためです。postgres:17(POSTGRES_VERSION 変数のデフォルト値)と redis:7 はメジャーバージョンに追従します。配布ファイルでは現在、docker.io/clickhouse/clickhouse-server に正確なバージョンタグを使用しており、ClickHouse のバージョンも固定しています。このルールは Langfuse 固有のものではありません。自己ホスト型の openGym ワークアウトトラッカー はこのスタックの一部だけを使用しますが、それでも名前付きの git タグを指定します。起動時にデータベースを自動マイグレーションするソフトウェアでは、通常の pull がスキーマ変更になる可能性があるためです。

起動します。

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

初回起動ではマイグレーションが実行されるため、何かが応答するまで 2、3 分待ってください。Web コンテナは起動すると Ready をログに出力します。docker compose ps では、状態 running のサービスが 6 つ表示されるはずです。コンテナがループして再起動する場合は、ログに原因が記録されています。ClickHouse のマイグレーションは Web コンテナの起動時に適用されるため、不正な CLICKHOUSE_MIGRATION_URL は、tail している worker のログではなく docker compose logs langfuse-web に現れます。この変数では port 9000 の ClickHouse native protocol を使用します。HTTP port 8123 ではありません。8123 を指定すると、Web コンテナの起動時マイグレーションが失敗します。worker は時間のかかるバックグラウンドマイグレーションを実行するため、それらの結果は worker のログに記録されます。

ホスト自体からヘルスチェックを実行します。

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

通常の /api/public/health 呼び出しで確認できるのは、API プロセスが稼働していることだけです。デフォルトではデータベースを確認しないためです。監視対象にするなら failIfDatabaseUnavailable=true 形式を使用してください。データベースに接続できない場合は 503 を返します。/api/public/ready は、Web コンテナがトラフィックを受け付ける準備ができると 200 を返し、シャットダウンを指示されると 500 を返します。どちらも通常の HTTP チェックなので、Uptime Kuma のステータスページで監視できます。エージェントが気付く前に、スタックが停止したことを把握できます。

TLS を前段に置き、不要なポートを閉じる

付属の compose ファイルでは、Web コンテナ用に 3000:3000、MinIO 用に 9090:9000 を公開します。どちらもすべてのインターフェースにバインドされます。パブリック IP では、ポート 3000 をスキャンした人が誰でもサインアップページに到達でき、ポート 9090 をスキャンした人は、未加工のプロンプトを格納したバケットに接続できます。

ファイアウォールルールだけでは、これらのポートは閉じません。Docker は nat テーブルに独自の DNAT ルールを書き込みます。これらのルールは、パケットが ufw の filter ルールに到達する前に評価されます。そのため、ufw deny 3000 を設定しても、公開ポートは開いたままです。この問題は非常に多いため、Docker の公開ポートが ufw を迂回する理由という専用ガイドがあります。代わりに、override ファイルで loopback にバインドします。公開ポートを置き換えるには、Docker Compose 2.24.4 以降で !override を使用してください。単純なリストでは、元のバインディングがマージされます。

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

NEXTAUTH_URL には、スキームを含む正確な公開アドレスを指定する必要があります。ログインフローは、この値からコールバック URL を生成します。HTTPS プロキシの背後で http://localhost:3000 のままにすると、サインインの往復処理で、ブラウザーが到達できない場所へリダイレクトされます。

次に、リバースプロキシを 127.0.0.1:3000 に向け、証明書をプロキシで管理します。同じ Compose プロジェクトで Traefik を使用する場合は、1 つの Traefik リバースプロキシの背後で複数のアプリを実行するで説明した labels を使い、Compose network 経由で langfuse-web:3000 にルーティングします。Langfuse だけをこのホストで実行する場合は、Caddy でも 2 行で同じ構成にできます。curl -sI https://langfuse.example.com/api/public/ready で確認し、続いて 2 台目のマシンから curl http://YOUR_IP:3000 に接続できないことを確認します。

MinIO には注意点があります。Langfuse は、メディアをアップロードする SDK と、メディアをブラウザーで読み込む処理の両方に、S3 エンドポイントを指す presigned URL を渡します。そのため、画像や音声を含むマルチモーダルトレースを使用する場合、MinIO を loopback のみにすると、他のマシンから添付ファイルをアップロードできず、ブラウザーでも読み込めません。プロキシを設定する前に blob storage の設定ページを確認してください。presigned URL に書き込まれるエンドポイント LANGFUSE_S3_MEDIA_UPLOAD_ENDPOINT は、公開するエンドポイントと一致している必要があります。プレーンテキストのトレースには影響しません。

初回アクセス時にアカウントを作成し、その後はインスタンスを自分専用にします。アカウントを作成したら AUTH_DISABLE_SIGNUP=true を設定してください。ページに到達した第三者が登録できなくなります。Langfuse には LANGFUSE_ALLOWED_ORGANIZATION_CREATORS もあります。これは組織を作成できるユーザーを制限しますが、Enterprise Edition の機能であり、license key がある場合にのみ有効になります。すでに自分の identity provider として Authentik を実行している場合、Langfuse は標準の OIDC 接続を受け付けます。そのため、アカウントは、このホストだけが管理するパスワード一覧ではなく、他のアプリと同じ ID 管理に従って作成・削除されます。

最初のトレースを送信する

Web インターフェースでプロジェクトを作成し、プロジェクト設定から公開キーと Secret キーをコピーします。Python SDK は3つの環境変数を読み取ります。

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

LANGFUSE_BASE_URLは、2026年3月にリリースされた SDK v4 での変数名です。古いコードや古いガイドでは LANGFUSE_HOST が使われています。トレースが自分のサーバーではなく Langfuse Cloud に送信される場合は、ベース URL が未設定であることが原因です。未設定の場合、デフォルトでホステッドインスタンスが指定されるためです。

現在の Python SDK v5 には Python 3.11 以降と self-hosted Langfuse v4.59.0 以降が必要です。上記で固定したサーバーはこの要件を満たしています。

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()

@observeデコレーターは関数の周囲にオブザベーションを作成し、引数と戻り値を取得します。すでにアクティブなオブザベーションがあれば、その中にネストします。AnthropicInstrumentorは Anthropic クライアント用の OpenTelemetry インストゥルメンテーションです。各 messages.create呼び出しを、モデル名、トークン使用量、レイテンシを含む generation に変換します。呼び出し側のコードを変更する必要はありません。

確認は2つの呼び出しで実行できます。langfuse.auth_check()はキーが不正である場合やベース URL が間違っている場合に False を返します。ダッシュボードが空の理由を調べ続けるより迅速です。langfuse.flush()はキューに入った span の送信が完了するまでブロックします。短時間で終了するプロセスでは必要です。SDK はバックグラウンドでバッチ処理するため、スクリプトがすぐに終了すると未送信のバッチも失われるためです。1つのスクリプトではなくチーム全体でトレースを送信する場合は、各メンバーの shell ではなく、全員の agent がすでに経由している gateway で3つの変数を一度だけ設定します。これは self-hosted OneCLI ハーネスによって、キーを1か所で管理しながら各メンバーの実行をすべてインストルメントする方法です。

ClickHouse のデータが増え続けるのはなぜですか?

多くの人が自己ホストするデータの中で、最も速く増えるのはトレースです。エージェントを実行するたびに、各ステップについて 1 行が書き込まれます。入力と出力も完全な形で保存されるため、長いプロンプトを使う応答の多いエージェントは、監視対象のアプリケーションよりも 1 日あたりのデータ量がはるかに多くなります。放置すると ClickHouse がディスクを使い切り、ディスクが満杯になると処理が遅くなるのではなく、取り込みが停止します。

ここでは、増えるものが 2 つあり、それぞれに別の対策が必要です。

1 つ目は、独自のトレースデータです。対策は保持期間の設定です。自己ホスト環境では、データ保持は Enterprise Edition の機能であり、ライセンスキーが必要です。ライセンスキーがない場合、Langfuse はトレース、オブザベーション、スコア、メディアを無期限に保持します。そのため、それを前提にディスク容量を確保し、このセクションの最後にあるディスクアラートを利用してください。ライセンスがある場合、プロジェクト所有者または管理者がプロジェクト設定を開き、日数でデータ保持期間を設定できます。Langfuse が受け付ける最小値は 3 日です。夜間ジョブが保持期間を超えたトレース、オブザベーション、スコア、メディアアセットを選択し、ClickHouse と blob storage から削除します。ただし、保存済みのデータセット項目に関連付けられたメディアは除きます。このジョブにはバケットに対する DeleteObject 権限が必要です。デフォルトの compose ファイルにある MinIO の root 認証情報には、すでにこの権限があります。削除は復元できないため、長期的な履歴が必要な場合は、先に blob storage へのエクスポートを設定してください。Langfuse 自身のテーブルに TTL 句を手動で記述しないでください。保持ジョブが ClickHouse とバケットの状態を同期させますが、手動の TTL では片方だけが削除されます。

実際の利用状況に基づいて保持期間を選んでください。コストや品質の確認に必要なのは、数か月前のデータではなく、数日前のデータです。小規模なチームなら 30 日から始めるのが妥当です。問題が発生したときだけトレースを開くなら、14 日で十分です。

2 つ目は、ClickHouse 自身のシステムログテーブルです。保持期間を設定した後もディスク使用量が増え続けるため、これに気付かない人もいます。ClickHouse は自身の診断用に trace_log、text_log、opentelemetry_span_log、metric_log、asynchronous_metric_log、latency_log を書き込みます。これらには TTL が設定されておらず、Langfuse が読み取ることもありません。まず、実際にディスクを消費している場所を確認してください。

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
)

docker compose exec clickhouse clickhouse-client --password "$CLICKHOUSE_PASSWORD" で実行します。システムテーブルが上位にある場合は、設定オーバーレイで無効にしてください。ClickHouse は起動時に /etc/clickhouse-server/config.d/ 内のすべてのファイルをメイン設定に上書き適用します。

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

これをマウントして、ClickHouse を再起動します。

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

これで新しい書き込みは停止します。すでにディスク上にある行は残るため、DROP TABLE IF EXISTS system.trace_log で明示的に空き容量を回収し、削除した各テーブルについても同じ操作を行います。診断情報を保持したい場合は、remove="1" の代わりに各テーブルへ積極的な TTL を設定する方法もあります。Langfuse のスケーリングドキュメントに手順があります。これらの TTL 指定は、システムテーブルの初回作成時にのみ適用されます。そのため、既存のインストール環境では、同じドキュメントにテーブルへ後から適用する手順も記載されています。

もう 1 つ、把握しておくとよいテーブルがあります。blob_storage_file_log は、バケットにアップロードされたイベントファイルを追跡します。バケットにもライフサイクルポリシーを設定する場合は、両者の状態がずれないよう、テーブルにも対応する TTL を設定してください。

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

データディスクには、単純な df -h アラートも設定してください。トレースは一定のペースでは増えません。新しいエージェントをデプロイした日に急増します。その最初の兆候が、取り込みの失敗にならないようにしてください。

Postgres と ClickHouse をバックアップする

Langfuse のバックアップは 3 つの要素で構成されます。Postgres にはユーザー、組織、プロジェクト、API キーが保存されます。ClickHouse にはトレースが保存されます。MinIO には未加工のイベントが保存されます。Postgres だけを復元すると、ログインはできても履歴がありません。ClickHouse だけを復元すると、誰もログインして確認できない履歴だけが残ります。この分離は Langfuse 固有のものではありません。自己ホスト型の Chatwoot サポートデスクも同じ構成で、uploads ディレクトリを含めずに取得した Postgres ダンプを復元すると、添付ファイルがすべて失われた会話だけが復元されます。

Postgres は通常の pg_dump です。これは Docker インストールで Langfuse のバックアップドキュメントが使用する方法です。

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

ClickHouse では、さらに注意が必要です。マージの実行中にライブのデータディレクトリをコピーすると、一貫性のあるバックアップにならないためです。1 台のサーバーで行う簡単な方法は、コンテナを停止してボリュームをアーカイブすることです。

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

docker volume ls が表示するボリューム名を使用してください。YAML に記述された名前は使用しません。ファイルには langfuse_clickhouse_data と記述されていますが、Compose はプロジェクト名を先頭に付けます。そのため、langfuse というディレクトリでクローンすると、langfuse_langfuse_clickhouse_data が生成されます。これを間違えると、docker run は警告なしに新しい空のボリュームを作成します。その結果、アーカイブには何も含まれません。

Langfuse は、取り込み要求ごとに未加工のイベントデータをバケットへアップロードし、失敗した取り込みジョブを再試行する際にそのデータを再読み込みします。そのため、ClickHouse を短時間停止しても、通常はその後にワーカーが再試行します。利用の少ない時間帯に実施し、停止時間を短くしてください。より負荷の高いインスタンスでは、ClickHouse 独自の BACKUP DATABASE default TO S3(...) ステートメントを使うと、サーバーを停止せずに一貫性のあるバックアップを作成できます。MinIO が 3 つ目の要素であり、mc mirror または MinIO のオフサーバーバケットへのレプリケーションで対応できます。どの方法で作成した場合も、サーバー外へ持ち出してください。VPS 上の暗号化された restic バックアップは、そのために使用します。

Redis にはキューとキャッシュが保存されます。未処理のイベントファイルがバケットに残っていても、Redis を失うとキューに入っていたジョブは破棄されます。

一貫性に関する注意点は実際に存在するため、明確にしておく価値があります。Postgres と ClickHouse は異なる時点でダンプされるため、復元後にトレースのないプロジェクト行が残ったり、すでに存在しないプロジェクトに属するトレースが残ったりする可能性があります。Langfuse はこの状態を許容しますが、2 つのダンプは近い時刻に、トラフィックの少ない時間帯で取得してください。イベントバケットが実質的な安全網です。Langfuse は取り込み要求ごとに未加工のイベントデータをそこへアップロードするためです。

少なくとも 1 回はスクラッチ環境へ復元してください。そうすれば、障害発生中ではなく、今の時点で間違ったボリューム名に気付けます。

最初に確認すること

最初の 1 週間で確認する価値があるのは、次の 4 つです。

  • トレースあたりのコスト。 Langfuse はモデル名とトークン使用量からコストを計算します。トレースをコスト順に並べ、最も高額なものを最初から最後まで読みます。原因は通常、肥大化したプロンプトです。文書全体をコンテキストに貼り付けている場合や、誰も整理していない会話履歴が含まれている場合があります。原因を確認できれば、AI エージェントのコストを制御する方法は推測ではなく、エンジニアリング上の作業になります。
  • 入力と出力に分けたトークン使用量。 入力トークンは数が多く、単価が低い一方、出力トークンは数が少なく、単価が高くなります。キャッシュされた入力はさらに安価です。同じ計算方法を Claude Code のトークン使用量の数え方で詳しく説明しています。この考え方は、自作するエージェントにも適用できます。
  • レイテンシのパーセンタイル。 中央値では問題が隠れます。タイムアウトは p95 と p99 に現れます。エージェントループ内では、p95 の遅いツール呼び出しが反復回数分だけ増幅されます。
  • 失敗したツール呼び出し。 レベル ERROR で観測結果を絞り込みます。5% の確率で失敗するツールは、全体の成功率では見えません。しかしトレースでは明確に確認できます。モデルが再試行し、その問題を回避するためにトークンを消費する様子を監視できます。

保持期間を設定し、毎週同じ曜日に確認するダッシュボードを、デプロイする日に決めます。誰も開かない可観測性ツールは、ディスクを埋めるだけのデータベースです。

FAQ

セルフホストの Langfuse にはどの程度のメモリが必要ですか?

4 CPU コア、16 GiB のメモリ、約 100 GiB のストレージを用意してください。これは、1 台の仮想マシンに対して Langfuse の Docker Compose ガイドが推奨する構成です。公開されている各コンポーネントの最小要件は、ClickHouse が 8 GiB、web コンテナと worker コンテナがそれぞれ 4 GiB です。同じページでは、Postgres は 4 GiB、Redis は 1.5 GiB、MinIO は 4 GiB とされています。6 つの合計は 25.5 GiB となり、16 GiB という Compose の推奨値を上回ります。

データ保持期間を設定した後も ClickHouse のディスク使用量が増え続けるのはなぜですか?

保持期間の設定が対象とするのは、Langfuse 自身のデータだけです。ClickHouse は診断用テーブル trace_log、text_log、opentelemetry_span_log、metric_log、asynchronous_metric_log、latency_log も個別に書き込みます。これらには TTL が設定されていません。system.parts をテーブル単位でグループ化して実行し、最も容量を使用しているテーブルを確認してください。その後、/etc/clickhouse-server/config.d/ 配下のファイルに remove="1" エントリを追加して未使用のテーブルを無効化し、ClickHouse を再起動します。すでに使用されている容量を解放するには、既存のテーブルも削除します。

Langfuse で設定できる最小のデータ保持期間はどのくらいですか?

3 日です。保持期間はプロジェクト設定でプロジェクトごとに設定するか、Organization Management API で設定します。夜間ジョブにより、保持期間を超えた traces、observations、scores、media assets が ClickHouse と blob storage の両方から削除されます。ただし、保存済みの dataset items に関連付けられた media は除外されます。セルフホスト環境では、この機能は Enterprise Edition の機能であり、license key が必要です。license key がない場合、データは無期限に保持されます。削除は元に戻せないため、その期間を超える履歴が必要な場合は、先に blob storage へのエクスポートを設定してください。

Postgres と ClickHouse の両方をバックアップする必要がありますか?

はい。両者が異なるデータを保持しているためです。Postgres には users、organisations、projects、API keys が保存され、ClickHouse には trace データ本体が保存されます。Postgres だけを復元すると、ログインはできますが、データのないインスタンスになります。MinIO の bucket もバックアップしてください。ここには、Langfuse が受信時に永続化する raw events が保存されており、スタック内で source of truth に最も近いデータだからです。

既存の OpenTelemetry 環境をセルフホストの Langfuse に接続できますか?

はい。Langfuse v4 と現行の SDK は OpenTelemetry を基盤としており、Anthropic と OpenAI の OTel instrumentation は Langfuse に直接エクスポートできます。Python では pip install langfuse opentelemetry-instrumentation-anthropic を実行し、起動時に一度だけ AnthropicInstrumentor().instrument() を呼び出します。LANGFUSE_PUBLIC_KEY、LANGFUSE_SECRET_KEY、LANGFUSE_BASE_URL には独自の host を設定してください。ダッシュボードが見つからない場合は、調査を始める前に langfuse.auth_check() で動作を確認します。

この記事は役に立ちましたか?