Query reference: operators & syntax

How to filter — in both the Builder (structured rows) and SQL mode. The store is ClickHouse, so SQL mode is standard ClickHouse SQL. See Table & column reference for the columns.

Builder filter operators

Each + Add filter row is field · operator · value. Available operators:

OperatorMeaningExample value
= / !=Exact match / notlevel = error
IN / NOT INOne of a setnamespace IN (payments, checkout)
LIKE / NOT LIKEWildcard (% = any run, _ = one char)message LIKE %timeout%
> >= < <=Numeric / time comparisonduration_ns > 100000000

Filters combine with AND. For OR / regex / JSON-field logic, switch to SQL mode.

SQL mode — the patterns you'll actually use

Text search (substring, case-sensitive):

WHERE message LIKE '%connection refused%'

Case-insensitive: WHERE positionCaseInsensitive(message, 'refused') > 0.

Regex:

WHERE match(message, 'timeout|deadline exceeded')

Filter by a JSON attribute (labels, parsed_fields, span attributes are JSON strings):

-- spans where the HTTP status was 500
WHERE JSONExtractString(attributes, 'http.status_code') = '500'
-- logs for pods labelled team=payments
WHERE JSONExtractString(labels, 'team') = 'payments'

Time: use $from/$to (bound to the picker) or ClickHouse intervals:

WHERE timestamp > now() - INTERVAL 30 MINUTE      -- logs/metrics
WHERE start_time BETWEEN $from AND $to             -- spans use start_time

Duration (nanoseconds!):

-- spans slower than 250 ms
WHERE duration_ns > 250 * 1e6
SELECT name, duration_ns/1e6 AS ms FROM spans ORDER BY ms DESC

Aggregate:

SELECT service_name, quantile(0.99)(duration_ns)/1e6 AS p99_ms
FROM spans
WHERE start_time > now() - INTERVAL 1 HOUR
GROUP BY service_name
ORDER BY p99_ms DESC

Rules & limits

  • Read-only. INSERT / UPDATE / DELETE / DROP are rejected. Only SELECT.
  • 30-second timeout. Narrow the time window, add filters, or add LIMIT.
  • Export cap. Result export is capped at 100,000 rows — aggregate or LIMIT for larger sets.
  • Heavy queries run on a separate connection pool so they can't stall the rest of the UI.
  • Saving a Builder query writes to the URL — share the URL to reproduce it exactly.

Quick recipes

-- Top error messages, last hour
SELECT message, count() AS n FROM logs
WHERE level = 'error' AND timestamp > now() - INTERVAL 1 HOUR
GROUP BY message ORDER BY n DESC LIMIT 20;

-- All logs for one request (pivot from a trace)
SELECT timestamp, level, message FROM logs
WHERE trace_id = '<trace-id>' ORDER BY timestamp;

-- Error spans by service
SELECT service_name, count() AS errors FROM spans
WHERE status_code = 'ERROR' AND start_time > now() - INTERVAL 1 HOUR
GROUP BY service_name ORDER BY errors DESC;