> [!left-bubble] ![[colot-mini.webp]]
> [[GitHub Copilot CLI]]の `/research` で調査した結果です。
# GitHub Copilot CLI と Langfuse 接続時に Redis timeout / Web 固まり / Docker ハングが頻発する件の調査
## Executive Summary
今回の症状は、**Copilot CLI そのものよりも、self-hosted Langfuse を Docker Desktop 上で 1 台に同居させたときの資源不足・I/O 詰まり・Redis/BullMQ 依存**で説明できる可能性が高いです。Langfuse は Redis を単なるキャッシュではなく **ingestion のキュー基盤**として使っており、Redis が詰まると Web/API と worker の両方に波及します。[^1][^2][^3]
特に Langfuse の公式 sizing では、Web 4 GiB、Worker 4 GiB、Postgres 4 GiB、Redis 1.5 GiB、ClickHouse 8 GiB、MinIO 4 GiB が最小目安で、ローカルの Docker Compose 構成をそのまま載せると合計は **約 25.5 GiB** です。いっぽう Docker Desktop のメモリ上限は既定で **ホスト RAM の 50%** なので、16 GiB Mac だと既定 8 GiB、32 GiB Mac でも既定 16 GiB で、Langfuse の最小構成に対してかなり厳しいです。Docker 公式も、multi-container workload で遅くなるならメモリとディスク割り当てを増やすよう明記しています。[^4][^5][^6]
加えて、Langfuse には **Redis/BullMQ 周りの既知の回帰**があり、`v3.163.0` では self-hosted Redis/BullMQ 回りの不具合が報告され、該当コミットはその後すぐ revert されています。さらに現時点の docs は `REDIS_COMMAND_TIMEOUT` などの環境変数を案内している一方、現行 `main` の `env.ts` にはそれらが現れず、`redis.ts` 側では `socketTimeout: 30000` がハードコードされています。つまり、**ドキュメント通りに timeout を調整しても、実行中イメージで効いていない可能性**があります。[^7][^8][^9][^10][^11]
## Architecture / Failure Domain Overview
```text
Copilot CLI or bridge
│
▼
┌──────────────────┐
│ langfuse-web │ UI / API / ingestion entrypoint
└────────┬─────────┘
│ enqueue / cache
▼
┌──────────────────┐
│ Redis │ cache + BullMQ queue
└────────┬─────────┘
│ dequeue
▼
┌──────────────────┐
│ langfuse-worker │ event processing / background jobs
└──────┬─────┬─────┘
│ │
│ ├──────────────▶ S3 / MinIO
│
├────────────────────▶ ClickHouse
│
└────────────────────▶ Postgres
```
Langfuse の公式 docs は、Redis/Valkey を **caching layer and queue** と定義し、API で受けたイベントをすばやく受理して後段処理を遅延実行するために使うと説明しています。Redis 設定は **Langfuse Web と Worker の両方**に必要です。[^1]
実装上も、`IngestionQueue`、`OtelIngestionQueue`、`TraceUpsertQueue`、`ProjectDeleteQueue` などのキューはすべて Redis 上の BullMQ を使い、`enableOfflineQueue: false` と再接続戦略を前提に生成されています。つまり Redis の不調は「あとで回復する隠れた障害」ではなく、**かなり早く Web / worker のエラーや待ちに表面化する設計**です。[^8][^12][^13][^14]
## What Redis Is Actually Doing in Langfuse
### 1. Redis は ingestion の中心経路
公式 docs は Redis を「新しいイベントを API で素早く受け付け、処理と insert を後ろへ defer するための queue」と説明しています。これはまさに、Copilot CLI 側からまとまったイベントや trace が流れると Redis が最初の吸収層になることを意味します。[^1]
### 2. Web だけでなく worker も Redis に依存
デフォルトの `docker-compose.yml` では `langfuse-web` と `langfuse-worker` の両方が `redis` の healthcheck 成功に依存し、両方に `REDIS_HOST` / `REDIS_PORT` / `REDIS_AUTH` が設定されています。したがって Redis が詰まると、**UI/API 側だけでなく worker 側の job 処理も一緒に劣化**します。[^2]
### 3. queue は project/event 単位で shard 可能
`IngestionQueue` と `OtelIngestionQueue`、`TraceUpsertQueue` は shard 数を持ち、sharding key を SHA-256 ベースで shard index に写像しています。Redis cluster を使う高負荷運用では有効ですが、これは「高スループット前提の拡張策」であり、**ローカル Docker Desktop 1 台で起きる資源不足の第一対応ではありません**。[^12][^13][^15]
## Why This Looks More Like Local Infrastructure Saturation Than “Just Redis”
### 1. Docker Compose は Langfuse の本番向き構成ではない
Langfuse の Docker Compose ガイドは、これは「the simplest way to run Langfuse to give it a try」であり、**高可用性・高スループットには Kubernetes を推奨**すると書いています。Docker Compose 構成は HA、scaling、backup を欠きます。[^3]
### 2. 公式最小構成が Docker Desktop の既定より重い
Langfuse の sizing guide にある各コンポーネントの最小値を足すと、デフォルト compose 構成では Web 4 GiB + Worker 4 GiB + Postgres 4 GiB + Redis 1.5 GiB + ClickHouse 8 GiB + MinIO 4 GiB = **約 25.5 GiB** です。Docker Desktop は既定で Docker VM のメモリ上限をホストの 50% にするため、ローカル Mac では **Langfuse 最小構成に届かないまま**動かしているケースが珍しくありません。[^4][^5]
この条件だと、最初に破綻しやすいのは ClickHouse / MinIO / Postgres / Redis を含む Docker VM 全体で、結果として **Langfuse Web が固まる、Redis timeout が出る、最終的に `docker` コマンド自体の応答も悪くなる**という順で見えることがあります。これはアプリ単体バグというより、Docker Desktop 内部 VM のメモリ圧迫・ディスク圧迫・I/O 停滞で説明しやすいです。[^4][^5][^6]
### 3. Node.js 側の既定ヒープも詰まりやすさを増やす
Langfuse docs は Web / Worker の Node.js プロセスが既定では **最大 1.7 GiB heap** で動作し、コンテナに 4 GiB 割り当てていても Node 側の上限が低いと memory issues に遭遇すると説明しています。`NODE_OPTIONS=--max-old-space-size=...` を Web と Worker に設定するよう案内されています。[^16]
### 4. Docker Desktop は “multi-container が遅いならメモリとディスクを増やせ” と書いている
Docker Desktop docs は、multi-container workload で遅く感じるなら **memory と disk image space allocation を増やす**よう明記しています。また、共有ディレクトリが多すぎると host→VM 通知コストで **高 CPU / 遅い filesystem** を招き、DB や cache は bind mount より named volume / data volume の方がよいとしています。[^5][^6]
## Version-Specific Langfuse Pitfalls You Should Explicitly Rule Out
### A. `v3.163.0` の Redis/BullMQ 回帰
`langfuse/langfuse#12944` では、`v3.138.0` から `v3.163.0` へ上げた self-hosted 環境で、Web に `Error fetching key from redis Stream isn't writeable and enableOfflineQueue options is false`、worker に `Queue job ... errored` が連発する回帰が報告されています。[^7]
その直前のコミット `1463ddc1...` は「Redis outage 時に hang しない fail-fast」のために command/socket timeout を追加した変更で、BullMQ worker まで巻き込む構成でした。ところが、その後すぐ `21210296...` で **その変更全体が revert** されています。少なくともこの系統のバージョンでは、**Redis timeout 自体が既知の不安定要因**です。[^9][^10]
### B. docs と実装の timeout 設定が噛み合っていない
現行 docs は `REDIS_COMMAND_TIMEOUT`、`REDIS_REQUEST_SOCKET_TIMEOUT_MS`、`REDIS_BLOCKING_SOCKET_TIMEOUT_MS` を公開しています。[^11]
しかし現行 `main` の `env.ts` には Redis 関連変数として host/auth/TLS/cluster/sentinel などはあるものの、これら timeout 変数は見当たりません。いっぽう `redis.ts` では `keepAlive: 10000` と `socketTimeout: 30000` がデフォルトにハードコードされています。[^8][^17]
このため、**「docs を見て timeout 環境変数をいじったのに挙動が変わらない」**ということは十分ありえます。今使っている Docker image tag が本当にその env var を読む版なのか、先に確認した方がよいです。[^8][^11][^17]
## Not Every “Hang” Is Redis: Missing Worker Can Look Similar
`langfuse/langfuse#9900` では、OTEL endpoint が self-hosted で hang するという報告がありましたが、最終的には reporter 自身が **`langfuse-worker` が正しく起動していなかったのが原因**だと closing comment で認めています。 maintainer もローカルでは同じ curl が `200 OK` になることを確認していました。[^18]
つまり、今回のように「Redis timeout が目立つ」ケースでも、実際には
1. worker 不起動 / 再起動ループ
2. Docker VM の資源枯渇
3. ingress / proxy / file sharing 起因の I/O 停滞
が先に起き、その二次症状として Redis timeout が見えている可能性があります。[^5][^6][^18]
## Recommended Remediation Order
### 1. まず “Langfuse の中” ではなく “Docker VM 全体” を疑う
最優先で見るべきなのは Docker Desktop の VM 健全性です。Docker Desktop の割当メモリ・ディスクが小さいまま Langfuse の all-in-one compose を動かしているなら、そこが第一候補です。[^4][^5]
**推奨順**
1. Docker Desktop の **memory / disk image** を引き上げる。[^5]
2. Redis / Postgres / ClickHouse / MinIO のデータを **bind mount ではなく named volume** に寄せる。Docker docs も cache / DB は Linux VM 側 volume を推奨しています。[^6]
3. 可能なら **Redis を Docker Desktop 外へ逃がす**。最初に外出しするなら Redis が最も効果的です。Langfuse 自身も managed Redis/Valkey を許容しています。[^1]
### 2. Langfuse 側は “UI と ingestion を分離” する
Langfuse docs は、ingestion load が高いと **Web UI と API が slow or unresponsive** になりうるため、`langfuse-web` を ingestion 用と UI 用に分ける構成を推奨しています。`/api/public/ingestion*`、`/api/public/media*`、`/api/public/otel*` を ingestion 専用 replica に寄せるのが公式の案です。[^19]
Copilot CLI 由来で bursty にイベントが入るなら、**UI と ingestion を同じ web container に共存させない**のが一番効きます。[^1][^19]
### 3. Worker / Redis / Node メモリを明示的に整える
- Web / Worker に `NODE_OPTIONS=--max-old-space-size=...` を入れる。[^16]
- Redis は **version 7 以上**、`maxmemory-policy=noeviction` を守る。[^1]
- Redis CPU が高いなら、Langfuse docs は **4 CPU 以上**と cluster mode、必要なら queue sharding を推奨しています。[^20]
### 4. バージョン依存の不具合を切り分ける
もしあなたのイメージが **`v3.163.0` 近辺**なら、そのバージョン自体を疑ってください。self-hosted Redis/BullMQ 回りの回帰が報告され、関連コミットは revert されています。[^7][^9][^10]
逆に、docs にある timeout env var をいじっているなら、**今の image がその env var を読む実装か**を確認しないと無意味です。現行 `main` のコードだけ見る限り、`env.ts` と docs は完全には一致していません。[^8][^11][^17]
## Practical Triage Checklist
1. **Docker VM 健全性**
Docker Desktop の memory / disk 割当、ディスク残量、file sharing 設定を確認する。multi-container slowdown の公式対処はここです。[^5][^6]
2. **Worker 起動確認**
`langfuse-worker` が起動済みで、CrashLoop や restart を繰り返していないかを見る。worker 不起動は UI hang に見えることがあります。[^18]
3. **Redis 前提確認**
Redis 7 以上、`maxmemory-policy=noeviction`、Langfuse Web/Worker 双方への Redis 設定注入を確認する。[^1][^2]
4. **Langfuse Web と ingestion の分離**
UI と `/api/public/otel*` や `/api/public/ingestion*` を同じ web replica に載せ続けない。[^19]
5. **Version sanity check**
`v3.163.0` 近辺なら Redis/BullMQ 回帰の影響をまず疑う。timeout env var を使っている場合は docs/code mismatch も疑う。[^7][^8][^9][^10][^11][^17]
## Key Repositories Summary
| Repository | Purpose | Key files |
|---|---|---|
| [langfuse/langfuse](https://github.com/langfuse/langfuse) | Langfuse 本体実装 | `packages/shared/src/server/redis/redis.ts`, `packages/shared/src/server/redis/ingestionQueue.ts`, `packages/shared/src/server/redis/otelIngestionQueue.ts`, `packages/shared/src/server/redis/traceUpsert.ts`, `packages/shared/src/env.ts` |
| [langfuse/langfuse-docs](https://github.com/langfuse/langfuse-docs) | self-hosting / scaling / cache の公式 docs | `content/self-hosting/deployment/infrastructure/cache.mdx`, `content/self-hosting/deployment/docker-compose.mdx`, `content/self-hosting/configuration/scaling.mdx`, `content/self-hosting/deployment/infrastructure/containers.mdx` |
| [docker/docs](https://github.com/docker/docs) | Docker Desktop の resource / file sharing の公式 docs | `content/manuals/desktop/settings-and-maintenance/settings.md` |
## Confidence Assessment
**High confidence**
- Langfuse が Redis を queue として深く使っており、Redis 障害が Web/worker の両方に波及すること。[^1][^2][^8][^12][^13][^14]
- Docker Desktop 既定値のままローカル all-in-one Langfuse を載せると、メモリとディスクの観点で非常に詰まりやすいこと。[^4][^5][^6]
- `v3.163.0` 近辺に Redis/BullMQ 回帰があったこと。[^7][^9][^10]
**Medium confidence**
- あなたの個別症状の第一原因が「Redis 自身」ではなく「Docker Desktop VM 全体の資源不足」である、という優先順位付け。これは docs / 実装 / 既知事例からはかなり整合しますが、実機の `docker stats`、worker logs、Redis INFO、ディスク残量を見ていないため最終確定ではありません。[^4][^5][^6][^18]
**Assumptions / inferences**
- 「Copilot CLI と Langfuse を接続」は、Copilot CLI の出力や LLM 呼び出しを Langfuse 側へ何らかの bridge / SDK / OTEL 経路で流している、という意味で解釈しました。今回調べた一次情報の範囲では、Copilot CLI そのものの first-party Langfuse 連携仕様ではなく、**Langfuse self-hosting 側の failure domain** が主題です。
## Footnotes
[^1]: [langfuse/langfuse-docs](https://github.com/langfuse/langfuse-docs) `content/self-hosting/deployment/infrastructure/cache.mdx:16-32` — Redis/Valkey を caching layer and queue と説明し、Web/Worker 両方に設定が必要と明記。
[^2]: [langfuse/langfuse](https://github.com/langfuse/langfuse) `docker-compose.yml:7-16,59-65,90-99,151-167` (SHA `4879e0d2a734e27f770f7538b5fe7b03c38dd212`) — Web/Worker が Redis healthcheck に依存し、Redis 環境変数を共有している compose 定義。
[^3]: [langfuse/langfuse-docs](https://github.com/langfuse/langfuse-docs) `content/self-hosting/deployment/docker-compose.mdx:10-18` — Docker Compose は simplest way to try であり、高可用性・高スループットには Kubernetes 推奨。
[^4]: [langfuse/langfuse-docs](https://github.com/langfuse/langfuse-docs) `content/self-hosting/configuration/scaling.mdx:12-21` — Web 4 GiB、Worker 4 GiB、Postgres 4 GiB、Redis 1.5 GiB、ClickHouse 8 GiB、MinIO 4 GiB の最小要件。
[^5]: [docker/docs](https://github.com/docker/docs) `content/manuals/desktop/settings-and-maintenance/settings.md:57-77` (commit `c26f1cb309d220de3af7b4230550199221873faa`) — Docker Desktop の memory limit は Docker VM への割当で、既定は host memory の 50%、multi-container が遅いなら memory / disk allocation を増やすよう案内。
[^6]: [docker/docs](https://github.com/docker/docs) `content/manuals/desktop/settings-and-maintenance/settings.md:79-99` (commit `c26f1cb309d220de3af7b4230550199221873faa`) — file sharing は高 CPU / 遅い filesystem の原因になりうること、cache / DB は named volume など Linux VM 側へ置く方がよいことを説明。
[^7]: [langfuse/langfuse#12944](https://github.com/langfuse/langfuse/issues/12944) issue body (`2026-04-01`) — self-hosted `v3.163.0` で `Stream isn't writeable and enableOfflineQueue options is false` を伴う Redis/BullMQ 回帰を報告。
[^8]: [langfuse/langfuse](https://github.com/langfuse/langfuse) `packages/shared/src/server/redis/redis.ts:6-36` (SHA `d1281e513d6dad195511a4593a15d9022f356829`) — `keepAlive: 10000` と `socketTimeout: 30000` のデフォルト、再接続戦略、READONLY 時の reconnect を実装。
[^9]: [langfuse/langfuse](https://github.com/langfuse/langfuse/commit/1463ddc1aaf82e1dc3d70b4532ed4938a0a684f8) — `feat(redis): add command and socket timeouts for fail-fast behavior during outages (#12574)`。self-hosted Redis outage 時の hang 回避のため timeout を追加したコミット。
[^10]: [langfuse/langfuse](https://github.com/langfuse/langfuse/commit/21210296637a0539d2b28b794fa7427c1eabd2ef) — `revert(redis): add command and socket timeouts (#12930)`。上記変更を丸ごと revert。
[^11]: [langfuse/langfuse-docs](https://github.com/langfuse/langfuse-docs) `content/self-hosting/deployment/infrastructure/cache.mdx:74-86` — `REDIS_COMMAND_TIMEOUT`、`REDIS_REQUEST_SOCKET_TIMEOUT_MS`、`REDIS_BLOCKING_SOCKET_TIMEOUT_MS` を docs で公開。
[^12]: [langfuse/langfuse](https://github.com/langfuse/langfuse) `packages/shared/src/server/redis/ingestionQueue.ts:16-20,45-69` (SHA `f7fb442fbb8035a209abcd9c63dfd69b08391e72`) — ingestion queue が shard され、Redis/BullMQ 上に `enableOfflineQueue: false` で構築される実装。
[^13]: [langfuse/langfuse](https://github.com/langfuse/langfuse) `packages/shared/src/server/redis/otelIngestionQueue.ts:13-20,42-71` (SHA `4c6c84a05a32f58b69365e1d75a6f721f6184985`) — OTEL ingestion queue も同じく Redis/BullMQ と `enableOfflineQueue: false` を利用。
[^14]: [langfuse/langfuse](https://github.com/langfuse/langfuse) `packages/shared/src/server/redis/traceUpsert.ts:13-20,42-71` (SHA `2e334d86b79ee219584df07918a1cdae361a3c99`); [langfuse/langfuse](https://github.com/langfuse/langfuse) `packages/shared/src/server/redis/projectDelete.ts:11-34` (SHA `868c0b12c5d7a77588198fec0b962634c9cfe5ec`) — trace upsert や project delete も Redis/BullMQ に依存。
[^15]: [langfuse/langfuse](https://github.com/langfuse/langfuse) `packages/shared/src/server/redis/sharding.ts:7-17` (SHA `bc15c10e39e8bcdf3c923cfc3d712aeb2544de81`) — shard index を SHA-256 ベースで決める実装。
[^16]: [langfuse/langfuse-docs](https://github.com/langfuse/langfuse-docs) `content/self-hosting/deployment/infrastructure/containers.mdx:22-36` — Web/Worker は最低 2 CPU / 4 GiB、Node.js heap 既定 1.7 GiB、`NODE_OPTIONS=--max-old-space-size=...` 推奨。
[^17]: [langfuse/langfuse](https://github.com/langfuse/langfuse) `packages/shared/src/env.ts:13-49` (SHA `12c0f5a247e68c2c9000cbce85fe3ddbd25f666a`); [langfuse/langfuse](https://github.com/langfuse/langfuse) `packages/shared/src/server/redis/redis.ts:6-11` (SHA `d1281e513d6dad195511a4593a15d9022f356829`) — 現行 `main` の env schema には timeout 系 Redis env var が見当たらず、`redis.ts` では `socketTimeout: 30000` を固定。
[^18]: [langfuse/langfuse#9900](https://github.com/langfuse/langfuse/issues/9900) issue body; maintainer comment by `Steffen911` on `2025-10-22` ([comment 3431122405](https://github.com/langfuse/langfuse/issues/9900#issuecomment-3431122405)); reporter close comment on `2025-10-22` ([comment 3433342962](https://github.com/langfuse/langfuse/issues/9900#issuecomment-3433342962)) — 一見 Redis/OTEL hang に見えた事象が、最終的には `langfuse-worker` 未起動の問題だったケース。
[^19]: [langfuse/langfuse-docs](https://github.com/langfuse/langfuse-docs) `content/self-hosting/configuration/scaling.mdx:44-48` — ingestion load が高いと UI / API が slow or unresponsive になりうるため、`langfuse-web` を ingestion 用と UI 用に分けることを推奨。
[^20]: [langfuse/langfuse-docs](https://github.com/langfuse/langfuse-docs) `content/self-hosting/configuration/scaling.mdx:107-119` — Redis CPU が高い場合は 4 CPU 以上、cluster mode、必要なら queue sharding を推奨。