Attribute search
Filter span and resource attributes alongside duration, status, kind, IDs and trace-level intrinsics
Search by attributes, duration, status and trace structure while PulsusDB compiles TraceQL into index-aware ClickHouse® database read plans built for fast answers
{ resource.service.name = "api" && duration > 1s }SELECT trace_id,
min(start_ts), max(end_ts)
FROM trace_spans
PREWHERE service = 'api'
AND start_ts BETWEEN $start AND $end
WHERE duration_ns > 1000000000
GROUP BY trace_id
PulsusDB stores trace data for the questions engineers ask. TraceQL filters can use span, resource, event, link and instrumentation attributes, then combine those spans through structural operators and trace-level context
Filter span and resource attributes alongside duration, status, kind, IDs and trace-level intrinsics
Express child, descendant, parent, ancestor and sibling relationships between matching spansets
Run instant and range TraceQL metrics queries over the same stored spans used for search
Fetch traces by ID, search with TraceQL and discover tag names and values through product-neutral APIs
Move from a simple selector to a complex expression and inspect the representative ClickHouse SQL shape PulsusDB produces at each level
A resource service filter maps directly to the physical service column and becomes an early ClickHouse PREWHERE constraint
{ resource.service.name = "checkout" } SELECT trace_id, max(timestamp_ns) AS bound_ts
FROM trace_spans
PREWHERE service = 'checkout'
WHERE timestamp_ns >= {start} AND timestamp_ns < {end}
GROUP BY trace_id
ORDER BY bound_ts DESC, trace_id ASC
LIMIT 20 TraceQL metrics can push the time buckets, duration predicate, distinct span count and service grouping into a single vectorised ClickHouse aggregation
{ duration > 1s } | rate() by (resource.service.name) SELECT
toUnixTimestamp64Milli(toStartOfInterval(
fromUnixTimestamp64Nano(timestamp_ns), INTERVAL 60000 MILLISECOND
)) AS t,
service AS g0,
uniqExact(trace_id, span_id) AS n
FROM trace_spans
WHERE timestamp_ns >= {start} AND timestamp_ns < {end}
AND duration_ns > 1000000000
GROUP BY t, g0
ORDER BY t ASC, g0 TraceQL compare builds a selected cohort inside a broader baseline, enriches both with root and indexed attributes, then cross-tabulates the values that distinguish failing spans
{ resource.service.name = "checkout" }
| compare({ span.http.status_code = "500" }) SELECT t, attribute_key, attribute_value,
countIf(is_selected = 0) AS baseline_count,
countIf(is_selected = 1) AS selected_count
FROM (
SELECT t, is_selected, kv.1 AS attribute_key, kv.2 AS attribute_value
FROM (
SELECT t, is_selected, arrayJoin([
('name', span_name), ('status', span_status),
('resource.service.name', service),
('rootServiceName', root_service)
]) AS kv
FROM (
SELECT t, trace_id, span_id, any(name) AS span_name,
any(status_code) AS span_status, any(service) AS service,
max((trace_id, span_id) IN (
SELECT trace_id, span_id FROM trace_attrs_idx
WHERE key = 'http.status_code' AND val = '500'
AND scope = 'span' AND date BETWEEN {d0} AND {d1}
)) AS is_selected
FROM trace_spans PREWHERE service = 'checkout'
WHERE timestamp_ns >= {start} AND timestamp_ns < {end}
GROUP BY t, trace_id, span_id
) AS cohort
LEFT JOIN ({root_span_projection}) AS roots USING (trace_id)
)
UNION ALL
SELECT cohort.t, cohort.is_selected,
concat(attrs.scope, '.', attrs.key), attrs.val
FROM ({deduplicated_cohort}) AS cohort
INNER JOIN (
SELECT DISTINCT trace_id, span_id, scope, key, val
FROM trace_attrs_idx WHERE date BETWEEN {d0} AND {d1}
) AS attrs USING (trace_id, span_id)
)
GROUP BY t, attribute_key, attribute_value
ORDER BY t ASC, attribute_key, attribute_value PulsusDB only pushes work into the ClickHouse database when it can preserve the language’s semantics. Everything else remains the query engine’s job
Use typed attributes, intrinsics and time bounds to build an index-aware candidate set
→Evaluate spanset operators against parent, child, ancestor, descendant and sibling relationships
→Group matching spans by trace and produce the search or metrics response your tooling expects
Use PulsusDB’s documented API directly. Compatibility aliases remain optional, so the platform is not defined by another product’s routing conventions
See the compatibility matrix ↗/api/traces/v1/searchTraceQL search/api/traces/v1/trace/{traceId}Trace by ID/api/traces/v1/metrics/query_rangeTrace metrics