Traza is a trace database for LLM and agent workloads. It runs as a single binary with no external database, no queue, and no coordinator.
Sub-millisecond trace lookup. 3.3 ms filtered search over a million spans. 208,000 spans/s sustained ingest. One process, one directory.
The server with the dashboard already built in. No Rust, no Node.
VERSION=0.22.2
PLATFORM=macos-aarch64 # or linux-x86_64, linux-aarch64
curl -LO https://github.com/toshish/traza/releases/download/v$VERSION/traza-$VERSION-$PLATFORM.tar.gz
tar xzf traza-$VERSION-$PLATFORM.tar.gz
cd traza-$VERSION-$PLATFORMdocker run -p 8080:8080 -v traza-data:/data \
-e TRAZA_TOKENS="rw:$(openssl rand -hex 16)" \
ghcr.io/toshish/traza:latestcargo install traza --locked --bin traza-serverInstalls the server and API. The dashboard ships with the release archives, or build it from ui/.
To embed the engine directly in your own process instead:
cargo add trazagit clone https://github.com/toshish/traza && cd traza
cargo build --release
(cd ui && npm ci && npm run build)./traza-servertraza-server listening on 127.0.0.1:8080
traza-server: durability=wal — acknowledged writes are fsynced to the write-ahead log and recovered on restart
traza-server serving dashboard from ./ui/dist
That is the whole setup. Data lands in ./data, the dashboard is on http://localhost:8080.
| Flag | Default | |
|---|---|---|
--data-dir DIR |
./data |
All state. One writer process per directory. |
--host ADDR |
127.0.0.1 |
A non-loopback bind requires TRAZA_TOKENS. |
--port PORT |
8080 |
0 binds an ephemeral port and announces it. |
--durability MODE |
wal |
buffered, wal, or flushed. Every response says which one answered. |
--profile NAME |
balanced |
throughput, balanced, or latency. Sets the write-path knobs together. |
--ttl-seconds N |
off | Retention window for spans, annotations and payloads. |
--mcp |
off | Serve Model Context Protocol at /v1/mcp. |
--ui-dir DIR |
beside the binary | Where the built dashboard lives. |
--restore DIR |
Install a backup into --data-dir, then serve it. |
|
TRAZA_TOKENS |
unset | Bearer auth, rw: and ro: scoped. |
--help prints all twenty-five. The configuration reference explains what each one costs.
Serving a team. Named paths, an open bind address with auth, thirty days of retention, and the agent endpoint on:
export TRAZA_TOKENS="rw:$(openssl rand -hex 16),ro:$(openssl rand -hex 16)"
./traza-server \
--data-dir /var/lib/traza \
--host 0.0.0.0 \
--ttl-seconds 2592000 \
--mcpBulk backfill. The throughput profile seals larger segments and lets more acknowledgements share one fsync, which is what you want when nothing is waiting on any single batch:
./traza-server --data-dir /var/lib/traza --profile throughputA client blocking on the acknowledgement. The latency profile trades peak ingest for a materially better p95:
./traza-server --data-dir /var/lib/traza --profile latencyTests and CI. buffered is the fastest mode and lossy by design, which is exactly right for a store you are about to throw away. Port 0 picks a free port and prints it, so parallel test runs do not collide:
./traza-server --data-dir "$(mktemp -d)" --port 0 --durability bufferedDebugging an agent from your terminal. Serve MCP, then point a client at it:
./traza-server --mcp
claude mcp add --transport http traza http://localhost:8080/v1/mcpBacking up a running server. Pin and verify a consistent copy, take it, then release the pin:
curl -X POST http://localhost:8080/v1/backups/nightly
cp -a ./data/pins/nightly /backups/traza-$(date +%F)
curl -X POST http://localhost:8080/v1/backups/nightly/releaseRestoring one. Verified before anything is swapped, then served:
./traza-server --data-dir /var/lib/traza --restore /backups/traza-2026-08-10curl -X POST http://localhost:8080/v1/spans \
-H 'Content-Type: application/json' \
-d '[{
"trace_id": "trace-1",
"span_id": "span-1",
"name": "charge",
"service": "checkout",
"start_time_unix_nano": 1700000000000000000,
"end_time_unix_nano": 1700000000002500000,
"status": "ok"
}]'{"accepted":1,"durability":"wal"}Or point an existing app at it with two environment variables:
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:8080
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobufApps instrumented with OpenLLMetry or the OpenTelemetry GenAI conventions arrive with sessions and token/cost analytics already populated. No attribute renaming, no mapping file.
Want a populated store to explore first? examples/mcp-demo/run.sh seeds agent tool-calling trees, retry storms and multi-turn sessions, then runs a scripted investigation against them.
Fast reads. Trace lookup at p95 0.64 ms and filtered search at p95 3.3 ms over a million spans. Full-text search across prompt text returns a selective term in 1.5 ms where scanning takes 1,258 ms.
One process. No metadata database, no column store, no lock service, no object store to configure. It starts in milliseconds, and there is no control plane to lose a quorum at 3am.
A small surface. Two direct dependencies, twelve packages in the whole lockfile, a 2.2 MB binary. HTTP, threading and file I/O are the standard library, and the crate is #![forbid(unsafe_code)].
Agent telemetry as the workload. Sessions, token and cost rollups, prompts and completions with large ones offloaded and deduplicated, evals and human feedback attached after the fact, live tail, and one-command dataset export.
An endpoint your agent can query. --mcp serves Model Context Protocol from the same binary and port: ten tools shaped like the questions people actually ask, with stored span text confined as untrusted and results bounded in tokens.
Durability you choose. Three acknowledgement modes, and every response states which one answered it. The suite proves them by killing the process, not by asserting.
Backup without stopping. One call pins and verifies a consistent copy of spans, annotations and payload bytes together. Restore is one flag.
| Trace lookup, 1M spans | p95 0.64 ms |
| Filtered search, 1M spans | p95 3.3 ms |
| Content search, selective term | 1.5 ms (1,258 ms scanning) |
Sustained ingest, wal |
208,973 spans/s |
| Binary | 2.2 MB |
| Direct dependencies | 2 |
Every number is produced by a benchmark bundled in this repo, run over the real HTTP path. The harness writes the records itself and refuses to publish a result it cannot stand behind. Run them yourself with cargo run --release --bin bench.
Disk cost is your binding constraint. Segments are uncompressed JSON plus indexes and cost 1.8–2.1× the bytes you send. A columnar engine writing compressed files to object storage will beat that by an order of magnitude. The exception is agent context: a repeated system prompt above the offload threshold is stored once, measured at 121:1 in Traza's favour.
You need metrics and logs in the same system. Traza stores traces and their analytics. That is the whole surface, on purpose.
You need horizontal scale-out today. Traza is single-node.
Everything is in docs/ — getting started, the HTTP API, LLM semantics, the MCP server, deployment, durability, backup and restore, capacity, and the engine internals.
See CONTRIBUTING.md. Stable Rust is the only dependency, ./ci.sh is the merge bar, and a new dependency needs a written reason.
Copyright © 2026 Toshish Jawale. Apache-2.0.