Database query details p95 query scans the full trace window and times out
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 9.9k
- Forks
- 471
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 117
Description
Description
Opening a database statement in Services > Database loads the Slowest 5% of Queries tile by calculating p95 across the selected trace window. On a high-volume trace source with a 24-hour window, the generated query times out after 60 seconds.
This is reproducible with the default OpenTelemetry-style trace schema, where Duration is numeric and database statements are read from SpanAttributes.
Environment
- HyperDX 2.35.0
- Self-hosted ClickStack
- Trace source using the standard
Duration UInt64andSpanAttributes Map(...)fields
Steps to reproduce
- Open Services > Database.
- Select a 24-hour time range on a high-volume trace source.
- Open one of the database statement rows.
- Observe the Slowest 5% of Queries tile in the detail drawer.
Generated query
Sanitized version of the query shown by HyperDX:
SELECT
quantile(0.95)(
toFloat64OrDefault(toString(Duration))
) AS p95_duration_ns,
p95_duration_ns / 1e6 AS p95
FROM traces
WHERE
Timestamp >= fromUnixTimestamp64Milli(...)
AND Timestamp <= fromUnixTimestamp64Milli(...)
AND coalesce(
nullIf(SpanAttributes['db.query.text'], ''),
nullIf(SpanAttributes['db.statement'], '')
) IN ('GET /resource/:id')
The request fails with:
Timeout exceeded: elapsed 60099 ms, maximum: 60000 ms:
While executing MergeTreeSelect(pool: ReadPool, algorithm: Thread).
EXPLAIN indexes = 1 shows timestamp and primary-key pruning, but the generated database-statement predicate does not select the available map-value skipping index. The query therefore evaluates the coalesced map lookup across the selected trace slice.
Duration is already UInt64, so converting it through String and then Float64 also appears unnecessary.
Relevant code
The behavior appears to come from these paths:
- ServiceDashboardDbQuerySidePanel.tsx, which adds the selected database statement as a filter.
- serviceDashboard.ts, which builds the default coalesced statement expression.
- ServiceDashboardSlowestEventsTile.tsx, which calculates the p95 threshold.
Expected behavior
The database query detail drawer should remain usable for common 24-hour ranges without requiring a higher timeout or a full scan of the selected trace slice.
Possible directions include preserving the native numeric type for Duration, allowing the database statement expression to point to an indexed or materialized column, or using a projection/aggregate path for the repeated percentile calculation.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read ServiceDashboardDbQuerySidePanel.tsx, serviceDashboard.ts, and ServiceDashboardSlowestEventsTile.tsx to trace how the statement filter and p95 query are built. Reproduce the timeout on a 24-hour high-volume trace source and inspect the generated query with EXPLAIN indexes = 1. Done means the database detail drawer remains usable without scanning the full selected trace slice or requiring a higher timeout.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- clickhouse, typescript
- Domain
- databases, observability, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100