neuron-explorer
Steering-first neuron explorer for Qwen3.5-4B: push every MLP neuron, keep every rollout, browse the results
LLM observability and evals in a single binary — traces, prompts, datasets, scores and review queues for LLM and agent apps, self-hosted.
Developer toolsGo · TypeScriptGitHub @tracepadOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
LLM observability and evals in a single binary: traces, prompts, datasets, scores and review queues for LLM and agent apps. Self-hosted, SQLite inside, OpenTelemetry-native, MCP and CLI for coding agents.
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
LLM observability and evals in a single binary.
Tracepad is a self-hosted home for the traces, prompts, datasets and scores of
your LLM and agent applications. It is one binary of about 20 MB with SQLite
inside — no Postgres, no ClickHouse, no Redis, no object store — and it has
been measured idling in under 30 MB of memory (the figures, with their dates,
are under What it is built for).Read the full README ↗LLM observability and evals in a single binary.
Tracepad is a self-hosted home for the traces, prompts, datasets and scores of your LLM and agent applications. It is one binary of about 20 MB with SQLite inside — no Postgres, no ClickHouse, no Redis, no object store — and it has been measured idling in under 30 MB of memory (the figures, with their dates, are under What it is built for).
Point any OpenTelemetry instrumentation at it, or an application that already sends traces with the Langfuse SDK, by changing an endpoint. Then close the loop in the same place: version prompts and deploy one by moving a label, run a dataset and compare two runs case by case, score traces from code, from an LLM judge you run, or by hand through review queues, and watch quality move next to cost and latency.
Everything Tracepad holds is readable over one API — from the web interface, the CLI in the same binary, or a read-only MCP server — so a coding agent can start from the trace instead of guessing. Retention, erasure of one user's data and a replayable OTLP export are built in. Apache-2.0, with nothing held back behind a licence key.
tracepad export --otlp to replay every byte you sent
anywhere else.Sized for a team, not a fleet: up to about a million spans a day on one ordinary machine (what it is built for). Coming from the Langfuse SDK? docs/langfuse-sdk.md is the switch, and docs/compare.md sets Tracepad beside the tools you may be weighing it against.
Status: beta. Tracepad runs real workloads, and what is stable and what may still change before 1.0 is written down in What beta means.
New here? docs/quickstart.md goes from nothing to a trace on screen. The documentation is also a searchable, versioned site at https://tracepad.github.io/tracepad/, with a version per release. Changes are listed in CHANGELOG.md, and CONTRIBUTING.md is the way in for a patch.
Stable — these change only by addition, or with a deprecation that keeps the old form working for at least one release and says so in the changelog:
/api/v1 and the OTLP ingest endpoints: endpoints,
fields and filters are added; a documented one is not renamed or removed. The
CLI's JSON output is that API's bytes, so it is as stable as the API.tracepad.db.pre-<NNNN>_<name>.bak)
before applying one. A downgrade is not supported, so back up before an
upgrade (docs/install.md).0.x minor release may, and the
changelog says where.May still change before 1.0: the tables the CLI prints for people, the layout of the web interface, the set of MCP tools, how the attribute mapping reads conventions that are still moving (the OpenTelemetry GenAI ones), and the defaults of a fresh install.
Not in the beta — planned for after it:
execute_tool) are stored and shown, but their attributes
are not read into model, tokens or the step's kind; they stay in the span's
metadata, and the raw bodies are kept for a later reading.tracepad doctor, a one-shot report to attach to an issue. Until then:
tracepad health, tracepad version and GET /api/v1/system.docker logs keeps it.Support is best effort from a small team: issues are read, fixes go into the newest release only (SECURITY.md).
With your coding agent, in two lines. The first goes into a terminal and
installs the binary and its agent skill, verified, into ~/.local/bin:
curl -fsSL https://tracepad.github.io/tracepad/install.sh | sh
The second goes into the agent (Claude Code, Codex, Cursor):
Set up Tracepad for this project: follow https://tracepad.github.io/tracepad/agent-setup.md
It starts a server on this machine, connects your application, reads the first
trace back and tells you what it did (docs/agent-setup.md).
Update Tracepad to the latest release: follow https://tracepad.github.io/tracepad/agent-upgrade.md
updates it later, with a backup first and a way back (docs/agent-upgrade.md).
Until 0.1.0 is out, the script installs the release candidate only when you name
it: … | TRACEPAD_VERSION=0.1.0-rc.1 sh.
By hand, in Docker, which needs nothing else installed:
docker run -d --name tracepad -v tracepad:/data -p 127.0.0.1:4318:4318 \
ghcr.io/tracepad/tracepad
docker logs tracepad # the first run prints your app's key, once
The port is published on this machine only: Tracepad speaks plain HTTP, and
serving it to anyone else is a job for a TLS proxy in front
(docs/docker.md). The image is also on Docker
Hub as tracepad/tracepad, the same one at the same digest
(docs/docker.md).
Or as a binary: the archives for Linux, macOS and Windows on Releases — one file, nothing to install alongside it. Both carry the web interface; both keep everything in one directory you choose. docs/install.md covers the binary (verifying the download, running it as a service, upgrading, backing up) and docs/docker.md the image (the volume, the permissions, upgrades).
From a checkout, make build produces the same binary and make image the
same image.
One binary over one embedded database, sized for the traces of a team rather than of a fleet. Up to roughly 10 GB of data and a million spans a day is the range Tracepad is written to serve well, on one ordinary machine and with nothing else to run. Past that you are looking for a platform on a column store — ClickHouse and its neighbours — and the honest answer is that this is not that.
Rough figures, measured on a synthetic corpus of about 2,000 traces (the binary size and the empty server's memory were measured on 2026-10-04; the rest date from 2026-08-30 and have not been re-measured since):
darwin/arm64, 7.6 MiB gzipped.TRACEPAD_STORE_RAW, on by default).Distrust the disk figure first: that corpus has short payloads, and on real
prompts and completions it is the payloads and the raw batches that the file
is made of. The read and memory figures were taken at that corpus's size too,
and they move with it — though /api/v1/stats answers closed hours from an
hourly rollup, so a month's chart costs about what a day's does, and it keeps
answering about data the retention window has since deleted. Size all of it against
your own traffic, and give it a retention window — near the top of this
envelope that is not optional. The two ceilings are a stock and a flow, and
they are counted in different units: the flow is spans, the disk figure above
is per trace. At a handful of spans a trace, a million spans a day is on the
order of a gigabyte a day, and more once the payloads are real ones — so the
stock is spent in days, not months. Nothing is deleted until you set that
window, which is a default for a small deployment rather than for this range:
see docs/retention.md.
Tracepad accepts standard OTLP/HTTP on /v1/traces, and the same endpoint
under the Langfuse SDK's path. Connecting an instrumented application is an
endpoint and a header:
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:4318/v1/traces
export OTEL_EXPORTER_OTLP_HEADERS="authorization=Bearer tp-sk-…"
The first line is required wherever an SDK defaults to gRPC: Tracepad has no gRPC receiver, and an SDK left to its own default may choose it — the application runs, reports nothing and the trace list stays empty.
In Python and in Node there is also a package — a thin layer over the same OpenTelemetry SDK, which adds an exporter to the provider your application already has rather than replacing it:
pip install tracepad # or: npm install tracepad @opentelemetry/api
import tracepad
tracepad.init()
@tracepad.observe
def answer(question: str) -> str: ...
In Go, the same package with the shape of the OTel API — a context in, a
context out (go get github.com/tracepad/tracepad/sdk/go).
See docs/ingest.md for the endpoints, the auth schemes, the attribute conventions Tracepad understands, and the ingest configuration, docs/configuration.md for every environment variable, docs/sdk-python.md for the Python package, docs/sdk-js.md for the Node one and docs/sdk-go.md for the Go one.
The same binary takes quality scores for your traces and serves the prompts your application runs on, over a plain JSON API — so an eval loop can grade yesterday's traces and a deploy can be a label move:
curl -H "Authorization: Bearer tp-sk-…" localhost:4318/api/v1/scores \
-d '{"trace_id":"4f8c…","name":"helpfulness","value":0.9}'
curl -H "Authorization: Bearer tp-sk-…" \
"localhost:4318/api/v1/prompts/summarize?label=production"
See docs/scores.md and docs/prompts.md.
Everything Tracepad knows is readable over HTTP, and the read API is written
for agents first: flat JSON, cursor pagination, a byte budget so a response
never quietly eats a context window, and task shortcuts instead of only REST
listings. Reading takes a key that holds the read scope, which the key the
first run prints does not: it is for your application, and it sits in a log.
Mint one in the interface, under Settings → Project → API keys
(docs/quickstart.md).
curl -H "Authorization: Bearer tp-sk-…" \
"localhost:4318/api/v1/traces/last?status=error&expand=io"
The question people actually arrive with is a piece of text — an error message somebody pasted, a sentence the model should not have said — so the listing searches what the observations carried, and every row says where it matched:
curl -H "Authorization: Bearer tp-sk-…" \
"localhost:4318/api/v1/traces?q=%22refund+failed%22"
The rest of what the SDKs already send is a filter too — which deployment a trace ran in, what kind of step it contains, which prompt produced an answer:
curl … "localhost:4318/api/v1/traces?release=2026.8.30&type=tool"
curl … "localhost:4318/api/v1/traces?prompt=support-answer@7"
The same question, three ways:
tracepad traces last --error --full # the CLI, in the same binary
{"mcpServers": {"tracepad": {"type": "http", "url": "http://localhost:4318/mcp",
"headers": {"Authorization": "Bearer tp-sk-…"}}}}
The CLI and the MCP server are HTTP clients of that API and contain no logic of their own, so all three return the same bytes. See docs/api.md, docs/cli.md and docs/mcp.md.
The MCP surface reads and nothing else — administration is deliberately not reachable as a tool.
A coding agent gets the order of work — start from the trace, read the payload before guessing at the prompt, dry-run anything destructive and ask — as a skill that ships inside the binary, so its version is always the server's:
tracepad skills install # into ~/.claude/skills; --project or --dir for elsewhere
See docs/agents.md.
The same binary serves a web interface on the same port. The first run prints the link that creates the account you will sign in with:
This server has no owner yet. Create the first one — it takes an email and a
password, and nothing is written down anywhere but this database:
http://localhost:4318/setup#token=…
People sign in with an email and a password; keys stay what they are, for
programs, each minted with the scopes its program needs — ingest to send,
read to look, write to change (docs/api.md). An owner runs the server and invites everyone else into specific
projects as a viewer or an editor — see
docs/accounts.md.
A filterable, searchable trace list — a hit shows the text it matched under the row and opens the panel on the observation it came from; a trace as its observation tree with the payloads of whichever span you are looking at; sessions rolled up from the traces that named them; volume, cost, latency and errors over time; and settings, where a project's retention, keys and data live — with an administration section that unlocks with the admin token for project lifecycle.
It is a client of the read API like the CLI and the MCP server, it keeps what you are looking at in the URL, and it makes no request to any origin but your own server — fonts and charts included. See docs/ui.md.
Nothing is deleted until you say so, and then it is deleted on a schedule rather than by hand:
tracepad retention set --days 90 # traces, counted from when they arrived
tracepad users rm-data user-4711 # everything the store holds about one user
An hourly sweeper removes what has expired, in chunks through the same writer
as ingest, and hands the freed pages back so the file shrinks. The statistics
survive it: the hourly rollup keeps answering about a window whose traces are
gone, until you give it a window of its own with --stats-days. Projects, keys
and retention windows are managed over the same API; every destructive call is
a dry run until you echo the name of what it destroys, and deleting a project
is undoable for a week. An erasure takes the user's data everywhere the store
holds it — the parsed rows, the scores on their sessions, the dataset items
cut from their traces and their spans in the raw OTLP archive — and the next
sweep overwrites the freed bytes; the
data-subject section
says exactly where its reach ends. See
docs/retention.md and docs/admin.md.
A picture a model was sent is stored once, not as base64 in every payload that carried it. Ingest takes data URLs, Anthropic and Gemini inline bodies and GenAI blob parts out of the JSON — for every client, the Langfuse SDK's own upload channel included — keeps each distinct file one time, and leaves a small reference in its place; the trace view shows the image. A project that must not keep pictures keeps only a placeholder. See docs/media.md.
Every export body Tracepad accepts is kept as it arrived — with media stored once beside it and put back on the way out — and one command replays it into any OTLP receiver — another Tracepad, a Collector, a vendor's endpoint — or onto disk:
tracepad export --otlp --to http://collector:4318/v1/traces
tracepad export --otlp --dir ./tracepad-export
In arrival order, resumably, and it reports what it could not cover: a trace older than the raw retention window has rows but no body, and nothing here invents one. See docs/export.md.
Apache-2.0. See LICENSE; third-party attributions are in
NOTICE. Every release archive and the image also carry
THIRD_PARTY_NOTICES, the licences of the Go modules and npm packages the
binary is built from (make notices writes it after make ui).