Skip to content

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:

  1. Your applications and agents emit OpenTelemetry traces, logs, and metrics.
  2. The collector receives them over OTLP and writes them into ClickHouse — otel_traces, otel_logs, otel_metrics_*, and so on.
  3. 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:

  1. 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.
  2. 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.
  3. The SQL runs against ClickHouse; results stream back to the browser, where the blocks render them.
  4. 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.