Why we built TQL instead of just teaching everyone SQL
Every telemetry platform eventually hits the same wall: the fast, cheap datastore for high-volume metrics is never the same engine as the relational store for platform data. In our case that's ClickHouse for traces, logs, and spans, and Postgres for organizations, projects, and alert rules.
The obvious answer is "just write SQL against both." We tried that for the first two years. It didn't hold up. ClickHouse doesn't support DATE_TRUNC or ILIKE. Postgres doesn't have AggregateFunction columns or quantileMerge. Every engineer on the team ended up keeping a mental translation table, and every on-call rotation lost minutes re-deriving which dialect applied to which table.
TQL exists to remove that translation step entirely. You write one query — filters, group-bys, aggregations — and TQL resolves it against whichever engine actually holds the data, rewriting syntax under the hood. A `p95(duration)` becomes a `quantileMerge(0.95)(duration_state)` against ClickHouse's materialized views, or a straightforward percentile function against Postgres, without you ever needing to know which one fired.
The result isn't a new database. It's one surface for asking questions of your telemetry, so the person debugging a 3am incident doesn't also need to remember which of two SQL dialects they're supposed to be writing.

