Release HyperDX - #3088
Open
github-actions[bot] wants to merge 2 commits into
Open
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
|
PR author is in the excluded authors list. |
github-actions
Bot
force-pushed
the
changeset-release/main
branch
16 times, most recently
from
September 10, 2026 23:37
eb331bc to
c96bd20
Compare
github-actions
Bot
force-pushed
the
changeset-release/main
branch
from
September 11, 2026 06:46
1e01248 to
2e17abc
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.
Releases
@hyperdx/api@2.39.0
Minor Changes
972634d: Report the whole alert condition in the
{{sourceQuery}}webhook templatevariable. It read only a chart's top-level
where, so an alert defined by aper-series
aggCondition— a common shape — still rendered empty. The variablenow reports every part of the condition the alert query actually applies: a
chart's
whereplus theaggConditionof the series the alert reads, and asaved search's
whereplus its pinned filters. A chart's pinned filters aredeliberately excluded, since a tile or inline alert does not apply them. The
value is truncated at 2000 characters.
Editing an alert off a
betweenoroutsidecomparator now clears the storedthresholdMaxinstead of leaving the old bound on the document, where it wasalso served by the alerts APIs and would advertise a range that no longer
fires. Webhook templates already guarded against this on read.
The webhook form's variable list and the API's fallback body template both
derive from one list in common-utils, which
buildWebhookTemplateVariablesistyped against, so a variable cannot be added without appearing in both places.
The "Send test" payload carries a sample value for every variable, so a body
template can be checked before an alert fires.
The documented guard for an optional number is now
{{#unless (eq thresholdMax undefined)}}rather than{{#if thresholdMax}},which treats a legitimate bound of
0as absent.Patch Changes
/api/sourcesresponses stable for sources whose storedmetadataMaterializedViewshas no nested_id@hyperdx/app@2.39.0
Minor Changes
41eee7d: Create and edit alerts from the chart explorer, without a saved search or dashboard tile. Build a chart on
/chart(logs, traces, or metrics — builder or raw SQL), add an alert, name it, and create it; the alert persists its own chart config. On the alerts page these alerts show their name with a chart icon and link back to the explorer seeded with their query, and the alert detail page renders that query and edits both the alert's fields and the chart behind it in the full chart editor.34d829c: feat: filter the LLM dashboard by end user
Adds a user filter alongside the existing session filter. It lists the distinct
users seen on LLM spans in the searched range and scopes every tab to the one
selected, including the Errors tab's correlated log events.
Users are resolved with the same cross-dialect expression the "Top Users" chart
groups by (
user.email,enduser.id,user.id,ai.telemetry.metadata.userId), so a value picked from the dropdown alwaysmatches the rows that produced it. The selection lives in the URL, so a filtered
view can be shared.
3876d6b: Fill the metric name select from the table's primary index, so it populates almost immediately instead of waiting on an aggregation over the data. On a source reporting ~4,900 gauge metrics the first options appear in ~30ms rather than ~770ms, and they stream in progressively rather than arriving all at once. A small spinner replaces the dropdown chevron while more are still on the way.
The picker now has two modes. Browsing streams
MetricNameout of the sparse primary index via themergeTreeIndextable function — one row per granule mark instead of a full column scan. Because the index only records the value at each granule boundary, that list is a subset, weighted towards metrics that actually carry data (index-visible metrics have a median ~32k datapoints against ~14 for the rest). Typing switches to the exhaustive, relevance-rankedGROUP BYsearch, so any metric the index omitted is still reachable by name. The placeholder reads "Search metrics..." to invite that.Two details that matter in use: while the first search for a pattern is in flight the browse list is held and filtered client-side, so the options never blank out mid-keystroke; and the dropdown's render cap is raised to 500 to match the server-side page size, so a search that is not reported as truncated is fully renderable.
Browsing falls back to the exhaustive listing when the index cannot be read at all — a server older than 24.2, a Distributed or non-MergeTree metric table, or a schema whose primary key omits
MetricName— so no deployment loses the picker.MetadatagainsstreamDistinctIndexValues, an async generator generic over table and column, so any primary-key column (ServiceName, for instance) can be listed the same way.streamToAsyncIteratormoves frompackages/app's session code intocommon-utilsbeside the ClickHouse client, and a newuseStreamingQueryhook accumulates an async iterable into a React Query cache entry, publishing partial results on a throttle.972634d: Report the whole alert condition in the
{{sourceQuery}}webhook templatevariable. It read only a chart's top-level
where, so an alert defined by aper-series
aggCondition— a common shape — still rendered empty. The variablenow reports every part of the condition the alert query actually applies: a
chart's
whereplus theaggConditionof the series the alert reads, and asaved search's
whereplus its pinned filters. A chart's pinned filters aredeliberately excluded, since a tile or inline alert does not apply them. The
value is truncated at 2000 characters.
Editing an alert off a
betweenoroutsidecomparator now clears the storedthresholdMaxinstead of leaving the old bound on the document, where it wasalso served by the alerts APIs and would advertise a range that no longer
fires. Webhook templates already guarded against this on read.
The webhook form's variable list and the API's fallback body template both
derive from one list in common-utils, which
buildWebhookTemplateVariablesistyped against, so a variable cannot be added without appearing in both places.
The "Send test" payload carries a sample value for every variable, so a body
template can be checked before an alert fires.
The documented guard for an optional number is now
{{#unless (eq thresholdMax undefined)}}rather than{{#if thresholdMax}},which treats a legitimate bound of
0as absent.Patch Changes
ab15643: Fix default time range resolution for long-lived sessions
71d792a: fix: Don't run ClickHouse queries for disabled sources on load. Disabled sources are now excluded from the metadata/field autocomplete and dashboard filter-value lookups that fire on page load, so loading a page no longer issues source-settings queries (e.g.
SELECT name, value FROM system.settings) for sources that are turned off.34d829c: fix: use mapContains for LLM dashboard attribute-presence filters
The LLM dashboard tested attribute presence with
SpanAttributes['key'] != '',which no skip index can serve — the trace schema's
mapKeys(SpanAttributes)index only answers
mapContains, and!= ''normalizes tonotEmpty(). Everytile therefore scanned all granules. Map subscripts are also subcolumn
references, so on ClickHouse 26.3+ each one adds a per-part size lookup during
PREWHERE planning.
These filters now lead with
mapContains, which the index serves and whichcosts no per-part lookups. On a staging trace table the LLM span predicate went
from a 36s planning stall to 7ms, and a two-key filter dropped from 1,306
granules to 3.
Gates that pair with a value expression the dashboard groups by keep their
non-empty check, so an attribute set to
''still cannot appear as a blank row.There the value term defines the result and the presence term is pruning only,
so it is wrapped in
indexHint— it reaches skip-index analysis without beingre-evaluated per surviving row. The value term costs no extra per-part lookups,
since it reads the same keys the group-by already reads. Gates that land in a
select-list aggregate are left unhinted, since skip-index analysis does not
reach the select list; the tool-call gate is used in both positions and so is
exposed in both forms.
The one behavior change is LLM span detection, which is now presence-based: a
span carrying
gen_ai.systemat all is treated as an LLM span whatever thevalue. Nothing groups by that predicate.
One caveat for tables with materialized columns: a
SpanAttributes['key']subscript gets rewritten onto a materialized column when an operator has created
one, and
mapContainsis not matched by that rewrite. Such tables were neveraffected by the planning cost either, since a rewritten subscript is no longer a
subcolumn reference — so this trades that rewrite for skip-index pruning, which
is the better deal only where those columns do not exist.
JSON attribute columns are unchanged — their paths are real subcolumns, there is
no key index to prune with, and a presence term would only duplicate reads.
96ac6b1: fix: disable per-part subcolumn size calculation on ClickHouse 26.3+
ClickHouse 26.3 turned on
allow_calculating_subcolumns_sizes_for_merge_tree_readingby default, whichmakes PREWHERE planning fetch per-part sizes for every map key a query
references. On SharedMergeTree that is one S3 GET per (key × active part), it
runs before any row is read, and
max_execution_timedoes not interrupt it.Queries referencing many attribute keys — the LLM dashboard reads ~64 — could
spend minutes in planning. Queries now send the setting as
0when the serversupports it.
cfacdbe: feat: relative date ranges for dashboards can now be saved
fda038d: fix: keep the LLM dashboard scope filters clearable when their options fail to
load
The session and user dropdowns were disabled whenever their distinct-value query
was loading or had failed. With a filter applied that left the user looking at a
scope they could see but could not remove — permanently, if the query kept
failing. They now stay interactive whenever a value is applied.
78a33ba: feat: Allow configuring dashboard filters as required
b484057: feat: Optionally apply the dashboard's filter selections to the tile editor preview
25695c1: Stop the Help menu sparkling on every deploy. The "you haven't read the latest release notes" indicator compared the browser's last acknowledgement against
NEXT_PUBLIC_APP_VERSION, which any deployment that stamps a build id into it (a git short SHA, a CI build number) changes on every deploy — so the nudge fired for every user every time whether a new release had been published or not. It now keys on the newest release version in the changelog, inlined at build time, and nudges only when that release is strictly newer than the one the browser has acknowledged, so a rollback no longer re-nudges everyone either.Updated dependencies [c8cc8e5]
Updated dependencies [96ac6b1]
Updated dependencies [cfacdbe]
Updated dependencies [78a33ba]
Updated dependencies [0a37198]
Updated dependencies [3876d6b]
Updated dependencies [b484057]
Updated dependencies [972634d]
@hyperdx/common-utils@0.29.0
Minor Changes
3876d6b: Fill the metric name select from the table's primary index, so it populates almost immediately instead of waiting on an aggregation over the data. On a source reporting ~4,900 gauge metrics the first options appear in ~30ms rather than ~770ms, and they stream in progressively rather than arriving all at once. A small spinner replaces the dropdown chevron while more are still on the way.
The picker now has two modes. Browsing streams
MetricNameout of the sparse primary index via themergeTreeIndextable function — one row per granule mark instead of a full column scan. Because the index only records the value at each granule boundary, that list is a subset, weighted towards metrics that actually carry data (index-visible metrics have a median ~32k datapoints against ~14 for the rest). Typing switches to the exhaustive, relevance-rankedGROUP BYsearch, so any metric the index omitted is still reachable by name. The placeholder reads "Search metrics..." to invite that.Two details that matter in use: while the first search for a pattern is in flight the browse list is held and filtered client-side, so the options never blank out mid-keystroke; and the dropdown's render cap is raised to 500 to match the server-side page size, so a search that is not reported as truncated is fully renderable.
Browsing falls back to the exhaustive listing when the index cannot be read at all — a server older than 24.2, a Distributed or non-MergeTree metric table, or a schema whose primary key omits
MetricName— so no deployment loses the picker.MetadatagainsstreamDistinctIndexValues, an async generator generic over table and column, so any primary-key column (ServiceName, for instance) can be listed the same way.streamToAsyncIteratormoves frompackages/app's session code intocommon-utilsbeside the ClickHouse client, and a newuseStreamingQueryhook accumulates an async iterable into a React Query cache entry, publishing partial results on a throttle.972634d: Report the whole alert condition in the
{{sourceQuery}}webhook templatevariable. It read only a chart's top-level
where, so an alert defined by aper-series
aggCondition— a common shape — still rendered empty. The variablenow reports every part of the condition the alert query actually applies: a
chart's
whereplus theaggConditionof the series the alert reads, and asaved search's
whereplus its pinned filters. A chart's pinned filters aredeliberately excluded, since a tile or inline alert does not apply them. The
value is truncated at 2000 characters.
Editing an alert off a
betweenoroutsidecomparator now clears the storedthresholdMaxinstead of leaving the old bound on the document, where it wasalso served by the alerts APIs and would advertise a range that no longer
fires. Webhook templates already guarded against this on read.
The webhook form's variable list and the API's fallback body template both
derive from one list in common-utils, which
buildWebhookTemplateVariablesistyped against, so a variable cannot be added without appearing in both places.
The "Send test" payload carries a sample value for every variable, so a body
template can be checked before an alert fires.
The documented guard for an optional number is now
{{#unless (eq thresholdMax undefined)}}rather than{{#if thresholdMax}},which treats a legitimate bound of
0as absent.Patch Changes
96ac6b1: fix: disable per-part subcolumn size calculation on ClickHouse 26.3+
ClickHouse 26.3 turned on
allow_calculating_subcolumns_sizes_for_merge_tree_readingby default, whichmakes PREWHERE planning fetch per-part sizes for every map key a query
references. On SharedMergeTree that is one S3 GET per (key × active part), it
runs before any row is read, and
max_execution_timedoes not interrupt it.Queries referencing many attribute keys — the LLM dashboard reads ~64 — could
spend minutes in planning. Queries now send the setting as
0when the serversupports it.
cfacdbe: feat: relative date ranges for dashboards can now be saved
78a33ba: feat: Allow configuring dashboard filters as required
b484057: feat: Optionally apply the dashboard's filter selections to the tile editor preview
@hyperdx/otel-collector@2.39.0
Minor Changes
7651bc3: feat: add text indexes for seeding the trace schema
fc4d587: feat(otel-collector): compile in spanmetricsconnector
Available for a user's own pipeline config (e.g. via
CUSTOM_OTELCOL_CONFIG_FILE) to compute call-count and durationmetrics from spans - most useful alongside the existing
datadogreceiversupport for ingesting Datadog Agent traces, wherethere was previously no way to derive RED metrics from that trace data
once ingested. Purely additive: being compiled in changes no default
pipeline or behavior on its own.