6 min read

Langfuse: See What Your LLM App Is Actually Doing (GitHub, Scanned)

Self-hostable tracing, prompt management and evaluations for apps built on language models.

Langfuse logo
✅
Scan: safe. Nothing malicious. Two things to know: a self-hosted instance reports usage counts to Langfuse unless you set TELEMETRY_ENABLED=false, and the Docker Compose file ships placeholder secrets with the web UI and MinIO open on all interfaces, so change them before it goes on a network. Scanned Oct 2, 2026; the full report is below.

Langfuse records what happens inside an AI application. Wrap your code with its SDK, or swap in its drop-in OpenAI client, and every model call, retrieval step, tool call and agent turn lands in a trace you can open in a web UI with inputs, outputs, latency, token counts and cost. When an answer goes wrong in production, you can see the exact prompt the model received and jump into a playground to work on it.

Around the tracing sit the parts teams otherwise build by hand: versioned prompt management, so prompts change without a redeploy; datasets for regression testing; and evaluations by LLM-as-a-judge, code, user feedback or manual labeling. It integrates with LangChain, LlamaIndex, the Vercel AI SDK, LiteLLM, Dify, Open WebUI and many of the other tools on this list.

The code is MIT licensed apart from the ee folders, which hold enterprise features under their own licence, and the project has about 35,000 stars. Langfuse has been part of ClickHouse since January 2026, and the self-hosted stack stores traces in the ClickHouse database. A managed cloud version has a free tier.

  • Repository: github.com/langfuse/langfuse
  • Licence: custom (Other)
  • Language: TypeScript. Stars: 35.3K. Forks: 3,911. Last push: Oct 2, 2026.
  • Scan: safe, Oct 2, 2026, commit f75c661

Who it is for

Developers and teams running LLM features in production who need to debug individual requests, track cost and quality over time, and manage prompts outside the codebase, especially those who want that data on their own servers.

Getting started

1. Self-host it on one machine with Docker Compose (UI on http://localhost:3000)

git clone --depth=1 https://github.com/langfuse/langfuse.git && cd langfuse && docker compose up

2. Install the Python SDK in your app

pip install langfuse openai

3. Point the SDK at your instance with keys from the project settings

export LANGFUSE_PUBLIC_KEY=pk-lf-... LANGFUSE_SECRET_KEY=sk-lf-... LANGFUSE_BASE_URL=http://localhost:3000

The Docker Compose setup is for one machine; the docs recommend Kubernetes with Helm for production, and there are Terraform templates for AWS, Azure and GCP. The compose file ships placeholder secrets marked CHANGEME, so replace them before the instance is reachable from a network, and set TELEMETRY_ENABLED=false if you do not want usage counts reported to Langfuse. Langfuse Cloud skips all of this.

Safety scan

We cloned langfuse/langfuse at commit f75c661 on Oct 2, 2026 and ran the checks described on the GitHub Tools page: credential patterns, decode-and-execute code, install-time scripts, committed binaries, risky CI workflows, every host the code talks to, known vulnerabilities in pinned dependencies, and project hygiene. A person read every hit. This is what we found.

  • No committed binaries across 6,525 files and about 1.3 million lines, almost all TypeScript. The 23 secret hits are test fixtures: Slack tokens such as xoxb-test-token in the Slack integration tests and placeholder PEM keys in AI-gateway and LLM-connection tests. The eight bare-IP URLs are tests proving that LLM base URLs and webhook targets are validated, using 1.1.1.1, a multicast and a broadcast address.
  • Pattern hits: the devcontainer Dockerfile installs ClickHouse with its official curl | sh, a Codex cloud setup script waits for ports using bash's /dev/tcp (flagged as a raw socket, but it only checks whether a service is up), and two very long lines are recorded trace fixtures.
  • We read the telemetry module. Self-hosted Langfuse sends PostHog a periodic count of projects, traces, observations, scores and dataset items with an instance identifier, and never trace contents or prompts. docker-compose.yml marks every default credential CHANGEME (NEXTAUTH_SECRET mysecret, an all-zero ENCRYPTION_KEY, minio and Redis passwords) and publishes the web UI on 3000 and MinIO on 9090 to all interfaces, while the databases stay on localhost.
  • pnpm-lock.yaml pins 2,418 packages with nine known advisories (3 high, 3 moderate, 3 low), all denial-of-service or build-time issues in basic-ftp, braces, deepmerge-ts, uuid, webpack and the AI SDK. The two Rust lockfiles, 404 crates for the AI gateway and native module, are clean. Install hooks enforce pnpm, run a repository helper and set up husky; a Rust build script compiles the native package.
  • 36 workflows. Three were flagged for pull_request_target: two labelling workflows with no PR checkout, and preview-build.yml, which actually runs on pull_request, builds only same-repository PRs, and uses AWS credentials scoped so that a pull_request_target run could not assume them; the scanner matched its explanatory comment. All 67 third-party actions are pinned to commits. Security policy, Dependabot, CodeQL, licence and contributing guide present.

What the scanner counted

CheckResult
Secrets23 candidates found and read; see the notes above.
Suspicious code4 pattern hits found and read; every one is listed under the raw findings.
Install-time code3 npm lifecycle scripts. 1 Cargo build script. 9 installer scripts (one can call sudo)
Committed binariesNone.
CI workflows36 workflows. 3 use pull_request_target, 1 of which check out the pull request head. 0 of 67 third-party actions pinned to a tag rather than a commit.
Network hosts40 distinct hosts referenced from source; most often langfuse.com, cloud.langfuse.com, github.com, api.openai.com. 8 URLs to a bare IP address, listed under the raw findings.
Known vulnerabilities9 advisories across 2,721 pinned packages: 0 critical, 3 high, 3 moderate, 3 low. ai-gateway/Cargo.lock: 229 packages, 0 advisories; packages/native/Cargo.lock: 175 packages, 0 advisories; pnpm-lock.yaml: 2,418 packages, 9 advisories.
Project hygieneHas security policy, automated dependency updates, CodeQL, licence file, contributing guide.
OpenSSF ScorecardNot scored: the project is not in Scorecard's weekly index.

The raw findings

Every hit the scanner wrote out, with a link to the exact line at the scanned commit. Secrets candidates are redacted.

Secret candidates (23, redacted)
WhereRuleMatch
packages/shared/src/server/llm/ai-sdk/requestShape.test.ts:167private-key-----B…--- (27 chars)
web/src/__tests__/server/automations-trpc.servertest.ts:1084slack-tokenxoxb-t…ken (15 chars)
web/src/__tests__/server/llm-connections-api.servertest.ts:37private-key-----B…--- (27 chars)
web/src/__tests__/server/slack-integration.servertest.ts:115slack-tokenxoxb-t…ret (22 chars)
web/src/__tests__/server/slack-integration.servertest.ts:133slack-tokenxoxb-t…ret (22 chars)
web/src/__tests__/server/slack-integration.servertest.ts:168slack-tokenxoxb-i…ken (18 chars)
web/src/__tests__/server/slack-integration.servertest.ts:186slack-tokenxoxb-i…ken (18 chars)
web/src/__tests__/server/slack-integration.servertest.ts:216slack-tokenxoxb-v…ken (16 chars)
web/src/__tests__/server/slack-integration.servertest.ts:233slack-tokenxoxb-v…ken (16 chars)
web/src/__tests__/server/slack-integration.servertest.ts:258slack-tokenxoxb-t…ken (15 chars)
web/src/__tests__/server/slack-integration.servertest.ts:288slack-tokenxoxb-t…ken (15 chars)
web/src/__tests__/server/slack-integration.servertest.ts:314slack-tokenxoxb-t…ken (15 chars)
web/src/__tests__/server/slack-integration.servertest.ts:337slack-tokenxoxb-t…ken (15 chars)
web/src/__tests__/server/slack-integration.servertest.ts:398slack-tokenxoxb-t…ken (15 chars)
web/src/__tests__/server/slack-integration.servertest.ts:445slack-tokenxoxb-t…ken (15 chars)
web/src/__tests__/server/slack-integration.servertest.ts:547slack-tokenxoxb-s…345 (27 chars)
web/src/__tests__/server/slack-integration.servertest.ts:567slack-tokenxoxb-s…ken (21 chars)
web/src/__tests__/server/slack-integration.servertest.ts:590slack-tokenxoxb-e…456 (40 chars)
web/src/__tests__/server/slack-integration.servertest.ts:619slack-tokenxoxb-e…ken (27 chars)
web/src/__tests__/server/slack-integration.servertest.ts:638slack-tokenxoxb-s…999 (27 chars)
web/src/__tests__/server/slack-integration.servertest.ts:667slack-tokenxoxb-s…ken (23 chars)
web/src/features/ai-gateway/server/auth/ingestionTokenVerifier.servertest.ts:13private-key-----B…--- (27 chars)
worker/src/__tests__/slack-processor.test.ts:91slack-tokenxoxb-t…ken (15 chars)
Pattern hits (4)
WhereRuleMatch
.devcontainer/Dockerfile:26download-piped-to-shellRUN curl https://clickhouse.com/ | sh && \
packages/shared/src/utils/normalized-io/conventions/providers/agno/fixtures.ts:34very-long-line5799 chars
scripts/codex/cloud_services.sh:294raw-socket-shelluntil (echo >"/dev/tcp/$host/$port") >/dev/null 2>&1; do
web/src/__tests__/server/otel-api.servertest.ts:346very-long-line8846 chars
URLs to bare IP addresses (8)
WhereRuleMatch
web/src/__tests__/server/llm-connections-api.servertest.ts:22ip-literal-urlconst TEST_PUBLIC_LLM_BASE_URL = "https://1.1.1.1/v1";
web/src/__tests__/server/llm-connections-api.servertest.ts:23ip-literal-urlconst TEST_UPDATED_PUBLIC_LLM_BASE_URL = "https://1.1.1.1/v2";
web/src/__tests__/server/llm-connections-api.servertest.ts:24ip-literal-urlconst TEST_CUSTOM_PUBLIC_LLM_BASE_URL = "https://1.1.1.1/custom/v1";
web/src/__tests__/server/llm-connections-api.servertest.ts:25ip-literal-urlconst TEST_SCHEMA_PUBLIC_LLM_BASE_URL = "https://1.1.1.1/schema/v1";
worker/src/__tests__/llm-base-url-validation.test.ts:135ip-literal-urlvalidateLlmConnectionBaseURL("https://1.1.1.1/v1"),
worker/src/__tests__/llm-base-url-validation.test.ts:179ip-literal-urlvalidateLlmConnectionBaseURL("http://1.1.1.1/v1"),
worker/src/__tests__/webhook-validation.test.ts:134ip-literal-urlawait expect(validateWebhookURL("http://224.0.0.1/hook")).rejects.toThrow(
worker/src/__tests__/webhook-validation.test.ts:142ip-literal-urlvalidateWebhookURL("http://255.255.255.255/hook"),
npm lifecycle scripts (3)
  • package.json preinstall: node -e "if (!process.env.npm_config_user_agent?.startsWith('pnpm/')) { console.error('This repository uses pnpm. Run pnpm install.'); process.exit(1); }"
  • package.json postinstall: node -e "const fs = require('node:fs'); const cp = require('node:child_process'); if (!fs.existsSync('scripts/postinstall.sh')) { console.log('Skipping repo postinstall helper: scripts/postinstall.sh …
  • package.json prepare: husky
Installer scripts (9)
Worst known vulnerabilities (9 of 9)
AdvisorySeverityPackageSummary
GHSA-c475-qrg2-pj4rhighbasic-ftp@5.3.1basic-ftp: Quadratic-time CPU denial of service in Client.list() Unix directory-listing parser (RE_LINE backtracking)
GHSA-vfj7-8cjw-p6xmhighbraces@3.0.3braces vulnerable to stack-exhaustion denial of service through deeply nested patterns
GHSA-ggr8-5vv4-36mxhighdeepmerge-ts@7.1.5DeepmergeTS has stack exhaustion when merging recursive object graphs
GHSA-w5hq-g745-h8pqmoderateuuid@10.0.0uuid: Missing buffer bounds check in v3/v5/v6 when buf is provided
GHSA-w5hq-g745-h8pqmoderateuuid@8.3.2uuid: Missing buffer bounds check in v3/v5/v6 when buf is provided
GHSA-w5hq-g745-h8pqmoderateuuid@9.0.1uuid: Missing buffer bounds check in v3/v5/v6 when buf is provided
GHSA-866g-f22w-33x8low@ai-sdk/provider-utils@2.2.8@ai-sdk/provider-utils has an Uncontrolled Resource Consumption issue
GHSA-38r7-794h-5758lowwebpack@5.97.1webpack buildHttp HttpUriPlugin allowedUris bypass via HTTP redirects → SSRF + cache persistence
GHSA-8fgc-7cc6-rx7xlowwebpack@5.97.1webpack buildHttp: allowedUris allow-list bypass via URL userinfo (@) leading to build-time SSRF behavior
Workflows worth a look

By the numbers

Stars35.3K
Forks3,911
Contributors217
Commits9,739
Open issues323
Open pull requests678
Releases705
Latest releasev4.50.0
Licencecustom
Main languageTypeScript
Project age3 years
Last pushOct 2, 2026
Tracked files6,525
Lines of code1.3M
Checkout size50 MB

Lines by language: TypeScript 1.1M, JSON 67.2K, Markdown 44.6K, YAML 38.8K, Rust 15.3K, JavaScript 11.2K.

Questions

Is Langfuse free?

Self-hosting is free: everything outside the ee folders is MIT licensed, and some enterprise features in those folders need a licence key. Langfuse Cloud has a free tier that needs no credit card, with paid plans above it.

Does Langfuse only work with OpenAI?

No. The Python and JavaScript SDKs trace any code you wrap, and there are integrations for Amazon Bedrock, Ollama, LangChain, LlamaIndex, LiteLLM, the Vercel AI SDK, CrewAI and many more, plus a public API with an OpenAPI spec.

Should I use Langfuse or promptfoo?

They do different jobs. promptfoo tests prompts and models from the command line before you ship. Langfuse watches the application after it ships, recording real traffic and scoring it. Plenty of teams use both, and Langfuse lists an integration with promptfoo.


This post is part of GitHub Tools, where every repository is cloned and scanned before it is written up. The scan is a snapshot of one commit on one day; the repository has moved on since, so check it before you install.