Architecture
Noemata isn’t one process — it’s a small set of long-running services that the CLI starts and supervises around your workspace. noemata up brings them all up; you mostly never think about them individually. This page is the map of what’s running and how data moves through it.
The pieces
- The CLI (
noemata) — the orchestrator. It reads your project config, then starts and supervises everything below, restarting and version-pinning the managed binaries as needed. One command (noemata up) is the entry point. - ClickHouse — the analytical database your observability data lives in. It’s where telemetry lands and what every frame ultimately queries.
- The OpenTelemetry collector — the ingestion path. It receives telemetry over OTLP and writes it into ClickHouse’s tables.
- The app server — serves the Noemata UI and the API behind it. It’s what turns a frame into a result: compiling its view and block queries into SQL, running them against ClickHouse, and streaming the data back to the browser.
- The sync daemon — keeps the file store and the files on disk in step, when the project is configured to sync.
The CLI runs each as a supervised process, with logs under .data/log/. Any of the data services can also be external instead of managed — point Noemata at a ClickHouse you already run, or an OTLP endpoint you already have — in which case the CLI skips starting that one and just connects.
How data gets in
Telemetry flows one direction, into the store:
- Your applications and agents emit OpenTelemetry traces, logs, and metrics.
- The collector receives them over OTLP and writes them into ClickHouse —
otel_traces,otel_logs,otel_metrics_*, and so on. - That’s it: the data is now queryable. Frames built on the OpenTelemetry semantic layer read straight from those tables.
See Send telemetry for the collector side, and Connect a database for pointing at data that’s already in ClickHouse.
How a frame renders
Reading data flows the other direction, on demand:
- You open a frame in the browser. Its page is a tree of blocks, each with queries written against the frame’s view — by column and metric name, not raw SQL.
- The app server compiles those named queries, plus the view, into concrete SQL, binding the frame’s parameters and the current time range and filters from context.
- The SQL runs against ClickHouse; results stream back to the browser, where the blocks render them.
- Change a control — the time range, a filter, a search — and only the affected queries re-run. The page is reactive because expressions are observable.
Where it all runs
By default everything is local: the CLI manages local ClickHouse and collector binaries and serves the UI from your machine, so a fresh noemata up is a self-contained stack with no external dependencies. From there you can swap individual pieces for external services, or change how the file store is backed — local disk, synced, or fully remote — without touching the rest. The knobs for all of that live in Configuration and the reference.