From 182c4a6636dc3986b591c6270aecd9dc0519c8ec Mon Sep 17 00:00:00 2001 From: Ravi Kumar L Date: Sun, 21 Jun 2026 23:54:06 +0200 Subject: [PATCH] feat: tune langfuse fanout batching --- .env.example | 2 ++ deploy-compose.langfuse-fanout.yml | 2 ++ docker-compose.langfuse-fanout.yml | 2 ++ helm/librechat/readme.md | 2 ++ .../templates/langfuse-fanout-configmap.yaml | 8 ++++---- .../templates/langfuse-fanout-deployment.yaml | 4 ++++ .../langfuse_fanout_config_drift_test.sh | 6 ++++++ helm/librechat/values.yaml | 2 ++ otel/langfuse-fanout/README.md | 7 +++++++ otel/langfuse-fanout/otelcol.yaml | 20 +++++++++---------- 10 files changed, 41 insertions(+), 14 deletions(-) diff --git a/.env.example b/.env.example index f4389279e1..1c93511068 100644 --- a/.env.example +++ b/.env.example @@ -148,6 +148,8 @@ NODE_MAX_OLD_SPACE_SIZE=6144 # LANGFUSE_FANOUT_TENANT_HIPAA_BASE_URL=https://hipaa.cloud.langfuse.com # LANGFUSE_FANOUT_MEMORY_LIMIT_MIB=256 # LANGFUSE_FANOUT_MEMORY_SPIKE_LIMIT_MIB=64 +# LANGFUSE_FANOUT_BATCH_TIMEOUT=1s +# LANGFUSE_FANOUT_BATCH_SEND_SIZE=128 # LANGFUSE_FANOUT_METADATA_CARDINALITY_LIMIT=1000 #=======================# diff --git a/deploy-compose.langfuse-fanout.yml b/deploy-compose.langfuse-fanout.yml index b63999a34e..91db513262 100644 --- a/deploy-compose.langfuse-fanout.yml +++ b/deploy-compose.langfuse-fanout.yml @@ -26,6 +26,8 @@ services: - LANGFUSE_FANOUT_TENANT_HIPAA_BASE_URL=${LANGFUSE_FANOUT_TENANT_HIPAA_BASE_URL:-https://hipaa.cloud.langfuse.com} - LANGFUSE_FANOUT_MEMORY_LIMIT_MIB=${LANGFUSE_FANOUT_MEMORY_LIMIT_MIB:-256} - LANGFUSE_FANOUT_MEMORY_SPIKE_LIMIT_MIB=${LANGFUSE_FANOUT_MEMORY_SPIKE_LIMIT_MIB:-64} + - LANGFUSE_FANOUT_BATCH_TIMEOUT=${LANGFUSE_FANOUT_BATCH_TIMEOUT:-1s} + - LANGFUSE_FANOUT_BATCH_SEND_SIZE=${LANGFUSE_FANOUT_BATCH_SEND_SIZE:-128} - LANGFUSE_FANOUT_METADATA_CARDINALITY_LIMIT=${LANGFUSE_FANOUT_METADATA_CARDINALITY_LIMIT:-1000} expose: - '4318' diff --git a/docker-compose.langfuse-fanout.yml b/docker-compose.langfuse-fanout.yml index b63999a34e..91db513262 100644 --- a/docker-compose.langfuse-fanout.yml +++ b/docker-compose.langfuse-fanout.yml @@ -26,6 +26,8 @@ services: - LANGFUSE_FANOUT_TENANT_HIPAA_BASE_URL=${LANGFUSE_FANOUT_TENANT_HIPAA_BASE_URL:-https://hipaa.cloud.langfuse.com} - LANGFUSE_FANOUT_MEMORY_LIMIT_MIB=${LANGFUSE_FANOUT_MEMORY_LIMIT_MIB:-256} - LANGFUSE_FANOUT_MEMORY_SPIKE_LIMIT_MIB=${LANGFUSE_FANOUT_MEMORY_SPIKE_LIMIT_MIB:-64} + - LANGFUSE_FANOUT_BATCH_TIMEOUT=${LANGFUSE_FANOUT_BATCH_TIMEOUT:-1s} + - LANGFUSE_FANOUT_BATCH_SEND_SIZE=${LANGFUSE_FANOUT_BATCH_SEND_SIZE:-128} - LANGFUSE_FANOUT_METADATA_CARDINALITY_LIMIT=${LANGFUSE_FANOUT_METADATA_CARDINALITY_LIMIT:-1000} expose: - '4318' diff --git a/helm/librechat/readme.md b/helm/librechat/readme.md index 964bceb213..19699cb1f6 100755 --- a/helm/librechat/readme.md +++ b/helm/librechat/readme.md @@ -72,6 +72,8 @@ if tenant keys and a known destination are configured. Langfuse tenant base URLs are selected from the startup-configured destination map rendered into LibreChat and the collector. Tenant API keys can still be added through tenant app configuration at runtime without restarting either component. +Collector batching can be tuned with `langfuseFanout.batchTimeout` and +`langfuseFanout.batchSendSize`; defaults are `1s` and `128`. See [`otel/langfuse-fanout/README.md`](../../otel/langfuse-fanout/README.md) for the central Langfuse secret and values example. diff --git a/helm/librechat/templates/langfuse-fanout-configmap.yaml b/helm/librechat/templates/langfuse-fanout-configmap.yaml index 3f0844b6e7..72da89ab88 100644 --- a/helm/librechat/templates/langfuse-fanout-configmap.yaml +++ b/helm/librechat/templates/langfuse-fanout-configmap.yaml @@ -49,12 +49,12 @@ data: - key: librechat.langfuse.destination action: delete batch/central: - timeout: 1s - send_batch_size: 128 + timeout: ${env:LANGFUSE_FANOUT_BATCH_TIMEOUT} + send_batch_size: ${env:LANGFUSE_FANOUT_BATCH_SEND_SIZE} {{- range $name, $_destination := .Values.langfuseFanout.tenant.destinations }} batch/by_auth_{{ $name }}: - timeout: 1s - send_batch_size: 128 + timeout: ${env:LANGFUSE_FANOUT_BATCH_TIMEOUT} + send_batch_size: ${env:LANGFUSE_FANOUT_BATCH_SEND_SIZE} metadata_keys: [authorization] metadata_cardinality_limit: ${env:LANGFUSE_FANOUT_METADATA_CARDINALITY_LIMIT} {{- end }} diff --git a/helm/librechat/templates/langfuse-fanout-deployment.yaml b/helm/librechat/templates/langfuse-fanout-deployment.yaml index cc7c7518b3..8ac8f04272 100644 --- a/helm/librechat/templates/langfuse-fanout-deployment.yaml +++ b/helm/librechat/templates/langfuse-fanout-deployment.yaml @@ -48,6 +48,10 @@ spec: value: {{ .Values.langfuseFanout.memoryLimitMiB | quote }} - name: LANGFUSE_FANOUT_MEMORY_SPIKE_LIMIT_MIB value: {{ .Values.langfuseFanout.memorySpikeLimitMiB | quote }} + - name: LANGFUSE_FANOUT_BATCH_TIMEOUT + value: {{ .Values.langfuseFanout.batchTimeout | quote }} + - name: LANGFUSE_FANOUT_BATCH_SEND_SIZE + value: {{ .Values.langfuseFanout.batchSendSize | quote }} - name: LANGFUSE_FANOUT_METADATA_CARDINALITY_LIMIT value: {{ .Values.langfuseFanout.metadataCardinalityLimit | quote }} volumeMounts: diff --git a/helm/librechat/tests/langfuse_fanout_config_drift_test.sh b/helm/librechat/tests/langfuse_fanout_config_drift_test.sh index 843e0eeea7..7e3807e2ac 100755 --- a/helm/librechat/tests/langfuse_fanout_config_drift_test.sh +++ b/helm/librechat/tests/langfuse_fanout_config_drift_test.sh @@ -142,6 +142,8 @@ function summarize(config) { return [ destination, { + timeout: batch?.timeout, + sendBatchSize: batch?.send_batch_size, metadataKeys: sorted(batch?.metadata_keys), metadataCardinalityLimit: batch?.metadata_cardinality_limit, }, @@ -158,6 +160,10 @@ function summarize(config) { tenantExportFilter: processors['filter/tenant_export']?.traces?.span ?? [], dropRoutingAttributes: processors['attributes/drop_librechat_routing']?.actions ?? [], centralExporter: exporters['otlphttp/central'] ?? {}, + centralBatch: { + timeout: processors['batch/central']?.timeout, + sendBatchSize: processors['batch/central']?.send_batch_size, + }, centralPipeline: pipelines['traces/central'] ?? {}, tenantRouterPipeline: pipelines['traces/tenant'] ?? {}, tenantExporters, diff --git a/helm/librechat/values.yaml b/helm/librechat/values.yaml index ae0c887199..d6503f2859 100755 --- a/helm/librechat/values.yaml +++ b/helm/librechat/values.yaml @@ -311,6 +311,8 @@ langfuseFanout: baseUrl: https://hipaa.cloud.langfuse.com memoryLimitMiB: 256 memorySpikeLimitMiB: 64 + batchTimeout: 1s + batchSendSize: 128 metadataCardinalityLimit: 1000 resources: {} podAnnotations: {} diff --git a/otel/langfuse-fanout/README.md b/otel/langfuse-fanout/README.md index 1e520718c3..447cf9a5a7 100644 --- a/otel/langfuse-fanout/README.md +++ b/otel/langfuse-fanout/README.md @@ -68,6 +68,8 @@ LANGFUSE_FANOUT_TENANT_US_BASE_URL=https://us.cloud.langfuse.com LANGFUSE_FANOUT_TENANT_JP_BASE_URL=https://jp.cloud.langfuse.com LANGFUSE_FANOUT_TENANT_HIPAA_BASE_URL=https://hipaa.cloud.langfuse.com LANGFUSE_FANOUT_TENANT_EXPORT_DISABLED=false +LANGFUSE_FANOUT_BATCH_TIMEOUT=1s +LANGFUSE_FANOUT_BATCH_SEND_SIZE=128 ``` Langfuse Cloud base URL options: @@ -123,6 +125,8 @@ langfuseFanout: baseUrl: https://jp.cloud.langfuse.com hipaa: baseUrl: https://hipaa.cloud.langfuse.com + batchTimeout: 1s + batchSendSize: 128 ``` The chart renders the collector Deployment, Service, and collector ConfigMap, @@ -139,5 +143,8 @@ the LibreChat app ConfigMap when they are not already supplied in override `langfuseFanout.tenant.destinations` in Helm for self-hosted or custom destinations. Compose's included collector config is static; if you add custom destination keys there, update or regenerate `otelcol.yaml` as well. +- `LANGFUSE_FANOUT_BATCH_TIMEOUT` and `LANGFUSE_FANOUT_BATCH_SEND_SIZE` tune + the OTel batch processors. The defaults (`1s`, `128`) favor low latency and + modest memory use; high-volume deployments may increase them for throughput. - `LANGFUSE_FANOUT_COLLECTOR_URL` is the local collector URL used by LibreChat, not a Langfuse Cloud base URL. diff --git a/otel/langfuse-fanout/otelcol.yaml b/otel/langfuse-fanout/otelcol.yaml index bcae8a574f..16abbad02d 100644 --- a/otel/langfuse-fanout/otelcol.yaml +++ b/otel/langfuse-fanout/otelcol.yaml @@ -47,26 +47,26 @@ processors: - key: librechat.langfuse.destination action: delete batch/central: - timeout: 1s - send_batch_size: 128 + timeout: ${env:LANGFUSE_FANOUT_BATCH_TIMEOUT} + send_batch_size: ${env:LANGFUSE_FANOUT_BATCH_SEND_SIZE} batch/by_auth_eu: - timeout: 1s - send_batch_size: 128 + timeout: ${env:LANGFUSE_FANOUT_BATCH_TIMEOUT} + send_batch_size: ${env:LANGFUSE_FANOUT_BATCH_SEND_SIZE} metadata_keys: [authorization] metadata_cardinality_limit: ${env:LANGFUSE_FANOUT_METADATA_CARDINALITY_LIMIT} batch/by_auth_us: - timeout: 1s - send_batch_size: 128 + timeout: ${env:LANGFUSE_FANOUT_BATCH_TIMEOUT} + send_batch_size: ${env:LANGFUSE_FANOUT_BATCH_SEND_SIZE} metadata_keys: [authorization] metadata_cardinality_limit: ${env:LANGFUSE_FANOUT_METADATA_CARDINALITY_LIMIT} batch/by_auth_jp: - timeout: 1s - send_batch_size: 128 + timeout: ${env:LANGFUSE_FANOUT_BATCH_TIMEOUT} + send_batch_size: ${env:LANGFUSE_FANOUT_BATCH_SEND_SIZE} metadata_keys: [authorization] metadata_cardinality_limit: ${env:LANGFUSE_FANOUT_METADATA_CARDINALITY_LIMIT} batch/by_auth_hipaa: - timeout: 1s - send_batch_size: 128 + timeout: ${env:LANGFUSE_FANOUT_BATCH_TIMEOUT} + send_batch_size: ${env:LANGFUSE_FANOUT_BATCH_SEND_SIZE} metadata_keys: [authorization] metadata_cardinality_limit: ${env:LANGFUSE_FANOUT_METADATA_CARDINALITY_LIMIT}