How it works
Aftertrace is one binary on your machine. Telemetry comes in, private fields are dropped, the rest goes into one DuckDB file, and SQL rules turn that file into findings you can read in the browser. Nothing leaves your machine unless you switch on Ask.
Point at a station to read it, and click it to open its page. With the figure focused, the arrow keys step through the stations and Enter opens one. C flips the content lever and A unlocks the outbox.
The path of one span
Here is what happens when Claude Code finishes one API request.
- Claude Code sends it, or Aftertrace reads it from disk. Live, the OpenTelemetry exporter batches the
claude_code.llm_requestspan and sends it to127.0.0.1:4317over gRPC or:4318over HTTP. On first launch, session JSONL already under~/.claude/projectsis imported as the same kind of rows, without prompt text. Receiving → · Local history → - The receiver decodes it. The batch is OTLP protobuf or JSON. It is turned into rows: traces become
spansandspan_events, logs becomeevents, metrics becomemetric_points. Receiving → - Redaction strips it. Account identifiers such as
user.emailare always deleted. Prompt, response and tool content is deleted unless you started with--store-content. Token counts, durations, model names and costs stay. Redaction → - The store keeps it. The rows go into
~/.aftertrace/aftertrace.duckdbin one write. If the same span arrives twice, it replaces itself. Views such asllmandtoolsturn the JSON attributes into columns. The store → - Rules read it. Fourteen SQL rules run against the store each time the app asks for findings, with results reused for up to 10 seconds. Each returns findings with a severity, an impact and the spans that prove it. Findings →
- You read it. The app on
127.0.0.1:7311shows the turn as a story: model thinking, tools running, time spent waiting on you. Reading a turn → - Ask, if you want it. Ask is off by default. With
--askand an Anthropic API key, a question in plain English is answered by Claude. It writes read-only SQL that runs here, and only the schema and trimmed result rows are sent to it. Ask →
What runs where
Everything above is one process, aftertrace serve. It opens three ports and one file.
| Part | Default | Change it with | Page |
|---|---|---|---|
| OTLP gRPC | 127.0.0.1:4317 |
--grpc-port, --listen |
Receiving |
| OTLP HTTP | 127.0.0.1:4318 |
--http-port, --listen |
Receiving |
| Identity keys | 6, always dropped | cannot be kept | Redaction |
| Content keys | 41 keys and 4 prefixes, dropped | --store-content |
Redaction |
| Database | ~/.aftertrace/aftertrace.duckdb |
--db |
The store |
| Tables | spans, span_events, events, metric_points |
The store | |
| Rules | 14, compiled into the binary | Writing rules | Findings |
| UI and JSON API | 127.0.0.1:7311 |
--ui-port, --listen |
Reading a turn |
| Ask | off | --ask and ANTHROPIC_API_KEY |
Ask |
To start sending data, see Install and Connect Claude Code.