OpenAI Codex tracing with Langfuse
What is Codex? Codex is OpenAI's agentic coding tool. It runs in your terminal (and IDE), understands your codebase, edits code, runs commands, and can spawn subagents to work on tasks in parallel.
What is Langfuse? Langfuse is an open-source AI engineering platform. It helps teams trace agentic applications, debug issues, evaluate quality, and monitor costs in production.
Install via the Codex plugin marketplace
The easiest way to set this up is the Langfuse Codex Plugin. Add the marketplace and enable the plugin:
codex plugin marketplace add langfuse/codex-observability-pluginThen install the tracing plugin, enable hooks, review and trust the Langfuse hook, and set your Langfuse keys (full steps below). Requires Node.js 22+ and Codex 0.146+.
What can this integration trace?
Using Codex's plugin hooks, this integration reads the transcript Codex writes for each session and sends it to Langfuse. You can monitor:
- User inputs: every prompt you send to Codex
- Model responses: assistant messages and reasoning summaries for each model call in a turn
- Tool calls: shell commands (
exec_command), file edits (apply_patch), MCP tools, web search, and subagent calls โ with their inputs, outputs, and error status - Token usage: input, output, cached, and reasoning tokens per model call, so you can monitor cost
- Subagents: subagent threads resolved from their own transcripts and nested under the spawning turn
- Sessions: all turns from one Codex session grouped together for replay
- Timing: accurate, backdated start and end times for every step
How it works
Codex provides a plugin system with hooks that run custom commands at lifecycle points. This integration uses the Stop hook, which runs after each Codex turn.
- The plugin registers a
Stophook that runs each time Codex finishes a turn. - The hook reads Codex's session transcript (the rollout file).
- Turns are reconstructed and converted into Langfuse traces using the Langfuse TypeScript SDK.
- All turns from the same session are grouped using a shared
session_id. - A small sidecar file records which turns were already uploaded, so resuming a session never creates duplicates.
Tracing is opt-in via the TRACE_TO_LANGFUSE environment variable. The hook fails open: if anything goes wrong, it logs and exits without blocking your Codex session.
Quick start
Set up Langfuse
- Sign up for Langfuse Cloud or self-host Langfuse.
- Create a new project and copy your API keys from the project settings.
Check your Codex version
These instructions require Codex 0.146 or later. Codex 0.146 removed the old plugin_hooks feature flag; use the current hooks flag shown below instead.
codex --version
codex features listIf your Codex version is older than 0.146, update Codex before installing the tracing plugin.
Add the plugin marketplace
Add the Langfuse marketplace via the Codex CLI:
codex plugin marketplace add langfuse/codex-observability-pluginInstall and enable the plugin
Install the tracing plugin from the marketplace:
codex plugin add tracing@codex-observability-pluginEnable hooks and the tracing plugin globally in ~/.codex/config.toml, or only for a specific project in <project>/.codex/config.toml:
[features]
hooks = true
[plugins."tracing@codex-observability-plugin"]
enabled = trueReview and trust the hook
Start Codex after installing and enabling the plugin:
codexWhen Hooks need review appears, review the Langfuse Stop hook and trust it. You can also type /hooks in the Codex CLI to inspect, review, and trust hooks.
Codex stores hook trust separately from plugin installation and plugin enablement. Plugin updates can change the hook definition hash, so Codex may require another review after an update.
Set your Langfuse credentials
Tracing stays off until TRACE_TO_LANGFUSE is "true", so you opt in explicitly. Add your credentials to your shell profile (~/.zshrc, ~/.bashrc, or ~/.bash_profile):
export TRACE_TO_LANGFUSE="true"
export LANGFUSE_PUBLIC_KEY="pk-lf-..."
export LANGFUSE_SECRET_KEY="sk-lf-..."
export LANGFUSE_BASE_URL="https://cloud.langfuse.com" # ๐ช๐บ EU regionAlternatively, create a JSON config file at ~/.codex/langfuse.json (global) or <project>/.codex/langfuse.json (per-project):
{
"enabled": true,
"public_key": "pk-lf-...",
"secret_key": "sk-lf-...",
"base_url": "https://cloud.langfuse.com"
}Configuration is resolved as defaults โ global config file โ project config file โ environment variables, with environment variables taking precedence. LANGFUSE_CODEX_* variables override the matching standard LANGFUSE_* variables, so you can scope credentials to Codex.
Restart Codex and verify tracing
Fully restart Codex after changing its global configuration, then start a new Codex session. Global configuration applies to new sessions in every project; existing sessions do not load the hook retroactively.
For a reliable test, send two short messages. The Stop hook uploads each completed turn, while the latest turn is finalized on the next hook invocation.
Run Codex as usual:
cd your-project
codexView traces in Langfuse
Open your Langfuse project to see the captured traces. Search for Codex Turn and widen the time range if needed; Langfuse timestamps may be displayed in UTC. The structure mirrors how Codex actually works:
- Turn trace (
Codex Turn): one trace per turn, from your prompt to the final answer, captured as an agent observation. - Generations: one per model response in the turn. Each shows the input it received, the model's reasoning and text, the tool calls it requested, and token usage.
- Tool spans (
exec_command,apply_patch,spawn_agent, โฆ): nested under the generation that triggered them, with input, output, and error status. Failed commands are flagged as errors. - Subagents: subagent threads are nested under the spawning turn so you can follow parallel work in one place.
- Sessions: all turns from the same Codex session are grouped via
session_idโ open the Sessions tab to replay the full run.
Environment variables
| Variable | Description | Required |
|---|---|---|
TRACE_TO_LANGFUSE | Set to "true" to enable tracing | Yes |
LANGFUSE_PUBLIC_KEY | Your Langfuse public key (pk-lf-...) | Yes |
LANGFUSE_SECRET_KEY | Your Langfuse secret key (sk-lf-...) | Yes |
LANGFUSE_BASE_URL | Langfuse host. EU: https://cloud.langfuse.com, US: https://us.cloud.langfuse.com, Japan: https://jp.cloud.langfuse.com, HIPAA: https://hipaa.cloud.langfuse.com | No (defaults to EU) |
LANGFUSE_TRACING_ENVIRONMENT | Environment label for the traces (e.g. production) | No |
LANGFUSE_CODEX_TAGS | Tags for all traces (JSON array or comma-separated) | No |
LANGFUSE_CODEX_METADATA | JSON object of metadata to attach to all traces | No |
LANGFUSE_CODEX_MAX_CHARS | Truncate inputs/outputs longer than this many characters (default 20000) | No |
LANGFUSE_CODEX_DEBUG | Set to "true" for verbose logging to stderr | No |
The credential variables also accept a LANGFUSE_CODEX_ prefix (for example LANGFUSE_CODEX_PUBLIC_KEY), which takes precedence over the standard variable.
Troubleshooting
No traces appearing in Langfuse
- Codex is too old. Run
codex --version. These instructions require Codex 0.146 or later because the oldplugin_hooksfeature flag was removed. Update Codex if your version is older. - Hooks are not enabled. Run
codex features listand confirm thehooksfeature is enabled. If it is disabled, sethooks = trueunder[features]in~/.codex/config.toml. - The plugin isn't installed or enabled. Run
codex plugin list --jsonand confirmtracing@codex-observability-pluginappears withinstalled: trueandenabled: true. If it is missing, runcodex plugin add tracing@codex-observability-plugin; if it is disabled, confirm the plugin table in~/.codex/config.tomlhasenabled = true. - The Stop hook is not trusted. "Installed" and "enabled" do not mean "trusted." Start Codex, open
/hooksif needed, then review and trust the LangfuseStophook. - Tracing isn't turned on.
TRACE_TO_LANGFUSEmust be the exact string"true"and visible to the Codex process, unless you enabled tracing in~/.codex/langfuse.json. Also verify the public key starts withpk-lf-. - Restart and test again. Fully restart Codex, start a new session, and send two short messages before checking Langfuse. A successful local test should show
hook: Stopfollowed byhook: Stop Completed. - Check the sidecar state. The plugin uses a
.langfusesidecar to remember which turns were uploaded. If you are retesting the same transcript, that state can prevent duplicate uploads. - Enable debug logging. Set
LANGFUSE_CODEX_DEBUG=trueto log to stderr and surface the actual cause.
Authentication errors
Verify your API keys are correct and that LANGFUSE_BASE_URL matches the region your keys belong to:
- EU region:
https://cloud.langfuse.com - US region:
https://us.cloud.langfuse.com - Japan region:
https://jp.cloud.langfuse.com - HIPAA region:
https://hipaa.cloud.langfuse.com
Data privacy
When enabled, the plugin uploads completed Codex transcript data to Langfuse, including prompts, assistant messages, reasoning summaries, tool inputs and outputs, model metadata, and token usage. Don't enable tracing for sessions containing data you don't want stored in Langfuse, and use LANGFUSE_CODEX_MAX_CHARS to cap how much of large inputs and outputs is captured.
Resources
- Langfuse Codex Plugin (GitHub)
- OpenAI Codex documentation
- OpenAI Codex hooks documentation
- Langfuse Sessions
- Langfuse TypeScript SDK
- Tracing coding agents with Langfuse
Last edited