v1 · stable wire API · Apache 2.0

Keep Grafana.
Swap the backend.

A drop-in Prometheus, Loki & Tempo HTTP gateway for ClickHouse. Point Grafana at cerberus as three datasources — your existing PromQL, LogQL and TraceQL keep working, translated to ClickHouse SQL underneath.

No Grafana plugin No custom query language No reinvented parsers
Get started
PromQL · LogQL · TraceQL one ClickHouse store Three signals, three query languages, one pipeline.
01 — THE GATEWAY

One guardian at the gate of three signals

Cerberus speaks each upstream HTTP API verbatim, so Grafana sees three ordinary datasources. Your dashboards, alerts and CLI tooling keep using the exact query languages they already use — cerberus does the translation.

PromQL

Metrics

Counters, gauges and histograms — translated to ClickHouse SQL and held at 574/574 on the CNCF PromQL Compliance Tester.

LogQL

Logs

Stream selectors, line filters and metric queries — diffed against a real Loki on Grafana's own bench corpus.

TraceQL

Traces

Span filters and structural queries served through the upstream Tempo HTTP API — the newest of the three heads.

02 — WHY CERBERUS

Three stores is a tax you stop paying

Metrics, logs and traces rarely share a store — the usual answer is Prometheus + Loki + Tempo: three retention policies and three storage bills for what is largely the same OTLP data sliced three ways. ClickHouse is a great single store for all three signals; cerberus supplies the missing query side.

No Grafana plugin

Cerberus speaks each upstream HTTP API verbatim — /api/v1/query_range, /loki/api/v1/query_range, /api/search. Grafana sees three normal datasources.

No custom QL

PromQL, LogQL, TraceQL — exactly as your dashboards and alerts already use them. Nothing to relearn.

No reinvented parsers

Imports prometheus/promql/parser, loki/logql/syntax and tempo/traceql directly. If upstream parses it, cerberus parses it.

03 — ARCHITECTURE

One query pipeline, not three

Each head parses with its reference upstream parser and lowers to a shared plan IR. A rule-based optimiser rewrites it; a closed typed-Frag emitter produces parameterised, escape-free ClickHouse SQL; the engine streams results. The three HTTP heads plug in as thin Lang adapters — so a new optimisation costs one implementation, not three.

PromQL
prometheus/promql/parser
LogQL
loki/v3/pkg/logql/syntax
TraceQL
tempo/pkg/traceql
internal/chplan — shared plan IR
Scan · Filter · Project · Aggregate · RangeWindow · Limit
internal/optimizer — rule-based, fixpoint
predicate pushdown · filter fusion · constant folding
internal/chsql — typed-Frag SQL emitter
parameterised · escape-free · streamed by internal/engine
ClickHouse

The three HTTP heads import their upstream parsers directly and lower into the same IR — so optimiser rules, the SQL builder and the execution engine are written once and shared. Cerberus reads the OpenTelemetry ClickHouse schema shape (column names, types, Map layout), not a specific exporter binary; CERBERUS_SCHEMA_* overrides handle SigNoz and custom layouts, and CERBERUS_AUTO_CREATE_SCHEMA bootstraps tables.

04 — INSIDE THE ENGINE

A real query engine, not a translator

Between the parser and ClickHouse sits an optimiser, a typed SQL builder and an execution engine with the resilience controls you expect from something on the hot path of every dashboard, alert and on-call query.

REQUIREMENTS
ClickHouse24.8+
OTel CH exporter schemaotel_metrics_* · otel_logs · otel_traces
native rate25.6+
05 — QUICK START

From clone to dashboards in one command

The compose stack builds cerberus, boots single-node ClickHouse, loads a deterministic OTel fixture, and brings up Grafana pre-provisioned with cerberus as three datasources. A fresh dashboard populates in ~30s.

shell — docker compose
# clone, build, and boot the full demo stack
git clone https://github.com/tsouza/cerberus.git && cd cerberus
docker compose up --wait

# Grafana auto-login on :3000 · cerberus on :8080
open http://localhost:3000
06 — CORRECTNESS

Held to reference, case for case

Every head is diffed against its real upstream engine on shared, seeded data — pinning observed semantics on ClickHouse against an oracle, not just emitted SQL. No allow-lists.

PromQL vs real Prometheus

Run through the third-party CNCF / PromLabs Compliance Tester against a real prom/prometheus seeded with identical data — the same suite the CNCF Prometheus Conformance Program uses. No allow-list.

CNCF / PromLabs Compliance Tester
LogQL vs real Loki

Diffed query-for-query against a real Loki on Grafana's own pkg/logql/bench corpus — responses compared on ClickHouse against the upstream engine, not just the emitted SQL.

differential harness · logql/bench corpus
TraceQL vs real Tempo

Served through the upstream Tempo HTTP API and diffed against a real Tempo on a maintained TXTAR query corpus — the newest head, validated the same case-for-case way.

differential harness · TXTAR corpus

Swap the backend, not the workflow

Open source under Apache 2.0. Point Grafana at cerberus and your PromQL, LogQL and TraceQL just work.