telemetryd
Architecture
Architecture
The path a record takes
POST /v1/logs
│
▼
decode + limits telemetryd-ingest
│ rejections counted, never silent
▼
write-ahead log telemetryd-store
│ durable before the response returns
▼
in-memory buffer queryable immediately
│
│ sealed on time or size
▼
Parquet segment immutable, never rewritten
│
▼
retention reaper deletes whole segments
The two properties worth noticing: a record is durable before the client is told it was accepted, and it is queryable before it is sealed. A telemetry store where the last hour is invisible would fail at the thing people actually use it for.
Crates
core ← store ← ingest ─┐
↖ query ──┴→ server → telemetryd (bin)
| Crate | Holds |
|---|---|
telemetryd-core |
Config, the error taxonomy, signal types, label matchers |
telemetryd-store |
Data directory, WAL, segments, retention, the query engine |
telemetryd-ingest |
OTLP JSON and remote_write decoders, limit enforcement |
telemetryd-query |
LogQL, TraceQL and PromQL subsets, and the three API shapes |
telemetryd-server |
axum router, auth, self-observability |
telemetryd |
CLI: serve, status, validate, service, version |
A strict DAG, no crate depending on a sibling above it. core is transport-agnostic —
it knows nothing about axum or HTTP — so the mapping from an error to a status code
lives in server and can change without touching the domain.
server is separate from the binary so the router can be driven in-process by contract
tests, with no socket and no argument parsing. That is why the test suite runs in
seconds.
Deliberate absences
Each of these is a thing telemetryd does not have, and the reason:
- No embedded key-value store. The segment catalogue is rebuilt at boot by scanning manifests — a few hundred small reads. One fewer dependency and one fewer corruption surface.
- No background compaction. Segments are sealed once and never rewritten. That is most of the single-host ingest advantage: no merge amplification.
- No query planner. The query shapes are known at compile time.
- No C dependencies at all. Which is what makes the static musl builds a straightforward link rather than a source of surprises.