Repository navigation
Release HyperDX - #3088
Merged
Merged
Release HyperDX#3088
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
Contributor
|
PR author is in the excluded authors list. |
github-actions
Bot
force-pushed
the
changeset-release/main
branch
20 times, most recently
from
September 14, 2026 05:36
2362cfe to
9b1f969
Compare
github-actions
Bot
force-pushed
the
changeset-release/main
branch
4 times, most recently
from
September 14, 2026 17:57
ea5db44 to
bf8cee1
Compare
github-actions
Bot
force-pushed
the
changeset-release/main
branch
3 times, most recently
from
September 15, 2026 10:50
bd18e83 to
999bea2
Compare
github-actions
Bot
force-pushed
the
changeset-release/main
branch
2 times, most recently
from
September 16, 2026 13:01
b1c0620 to
5002552
Compare
github-actions
Bot
force-pushed
the
changeset-release/main
branch
2 times, most recently
from
September 17, 2026 12:40
a108b39 to
c11ea0e
Compare
github-actions
Bot
force-pushed
the
changeset-release/main
branch
2 times, most recently
from
September 17, 2026 14:33
1fa03eb to
fb20ac8
Compare
github-actions
Bot
force-pushed
the
changeset-release/main
branch
from
September 17, 2026 21:34
dab1feb to
a3812ca
Compare
github-actions
Bot
force-pushed
the
changeset-release/main
branch
2 times, most recently
from
September 18, 2026 12:16
2cebcac to
e2dec94
Compare
github-actions
Bot
force-pushed
the
changeset-release/main
branch
2 times, most recently
from
September 18, 2026 16:19
a1da3ca to
ef08f03
Compare
github-actions
Bot
force-pushed
the
changeset-release/main
branch
from
September 18, 2026 17:50
e150798 to
685da21
Compare
wrn14897
approved these changes
Sep 18, 2026
Contributor
Author
🟢 Tier 1 — TrivialDocs, images, lock files, a dependency bump, or an automated release. No functional code changes detected. Why this tier:
Review process: Auto-merge once CI passes. No human review required. Stats
|
Contributor
Author
E2E Test Results✅ All tests passed • 375 passed • 1 skipped • 1201s
Tests ran across 4 shards in parallel. |
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
ff1e77c: Backfill alert
displayNameandtagsfrom the referenced saved search or dashboard on API startup. Alerts that already have a display name or tags are skipped.e31e5d8: Offer dashboard tile alerts for Terraform import.
clickhouse_clickstack_alertgained
source = "tile"withdashboard_id/tile_idin provider 3.28.0, sothe bulk export and the per-alert menu now include tile alerts instead of
skipping every alert that is not a saved-search one. A file carrying a tile
alert asks for
>= 3.28.0and explains the hand edit its generated configneeds; an export without one still installs on 3.25.x. A tile alert is withheld
when its tile has a blank or duplicated name — the provider's
tile_idsmap iskeyed by tile name and omits those, so the alert could only be pinned to a
literal id the next dashboard apply can re-mint — or when its dashboard is
provisioned, since ProvisionDashboardsTask rewrites those tiles wholesale. Both
decisions are made server-side, on the import manifest and on the alerts
listing, because neither response carries a dashboard's sibling tile names.
f007c37: Add a context-aware getting-started checklist to the sidebar for recently-created teams. After the setup steps (connect ClickHouse, add data) complete, a second phase tracks product-usage milestones persisted per user on
user.onboardingData: exploring data, building a dashboard, setting up an alert, and using the MCP server. Completion is recorded server-side so it counts from the UI, the external REST API v2, or an MCP tool; the card can be dismissed and reappears if a new task is added to the registry.b217430: feat: run PromQL against ClickHouse through its Prometheus HTTP API
ClickHouse-backed
/queryand/query_rangenow proxy to the connection's/prometheus/api/v1/*endpoint (theprometheus_api_v1HTTP handler, ClickHouse 26.8+) instead of calling theprometheusQuery/prometheusQueryRangetable functions. Thedatabaseandtablequery parameters are forwarded so one handler serves any TimeSeries table. ClickHouse holds the Prometheus API forward-compatible while the TimeSeries engine is in preview; the table functions and inner-table schema are not. Bundled ClickHouse images move to 26.8.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
4d18cb0: fix: fetch a grouped alert's example log lines once per window
A saved-search alert puts a handful of example log lines into the notification it sends, and fetching them takes a second query. That query was being made while building each message, so an alert grouped by service asked ClickHouse for the same lines once per breaching service — ten services meant ten identical queries over the same data, because the query only filters by the saved search and the time window, never by the group. It now runs once and every notification for that window shares the answer. An alert catching up on skipped ticks still fetches lines for each window it backfills, since those genuinely differ. Ungrouped alerts are unaffected; they only ever asked once.
c8cc8e5: feat: Include alert tags in the tags API response
482d2cb: feat: Paginate the alerts page
5311d63: fix: give incident.io webhooks a body incident.io accepts
An incident.io webhook saved without a body was sent the generic
{"text": ...}payload, which has neither of the two fields incident.io requires, so every delivery was rejected and no alert was ever raised. It now gets an incident.io payload carrying a deduplication key that is stable across a firing and its resolve, so incident.io closes the alert it opened, plus the alert id, status, condition and evaluation window inmetadatafor routing. The webhook body editor and its list of template variables are also available when incident.io is the selected service, not only for Generic, so the payload can be tailored to an alert source's configured fields.6b39171: Accept metric selects without a value expression on the external dashboards API. A tile that aggregates a metric names its value with
metricNameand has no expression to give, so/api/v2/dashboards/validatewas rejecting dashboards the editor itself writes, and Terraform could not import them.84c67f4: fix: show only the delivery time in an alert's notification duration
The notification duration on an alert's evaluation list was timing everything an alert does once it decides to fire: building the message title and links, querying the log lines that go in the body, rendering the template, and then delivering it. That made the column read in seconds while the webhook underneath it answered in milliseconds — the column and its own per-target breakdown disagreed, and the figure was dominated by work that has nothing to do with how fast the notification target responded. It now times the delivery alone. Evaluations already recorded keep their old figure and will read high.
cfacdbe: feat: relative date ranges for dashboards can now be saved
806d242: feat: page and filter GET /alerts server-side
b19fa12: refactor(api): backport alertConfigHasGroupBy helper
78a33ba: feat: Allow configuring dashboard filters as required
edb693a: Apply saved-search pinned filters to alert notification sample queries so sample
log lines come from the same row set the alert counted.
0a37198: fix: Keep
/api/sourcesresponses stable for sources whose storedmetadataMaterializedViewshas no nested_idbef61fb: feat: Scope tags endpoint by resource type
6c85ca0: feat: add a pluggable token encryption service for stored third-party tokens. Set
TOKEN_ENCRYPTION_KEYto a 32-byte key (base64 or hex) to encrypt them with AES-256-GCM; without it they are stored unencrypted.Updated dependencies [482d2cb]
Updated dependencies [e31e5d8]
Updated dependencies [5311d63]
Updated dependencies [96ac6b1]
Updated dependencies [84c67f4]
Updated dependencies [f007c37]
Updated dependencies [cfacdbe]
Updated dependencies [806d242]
Updated dependencies [f7ae72c]
Updated dependencies [b1e48b9]
Updated dependencies [78a33ba]
Updated dependencies [3876d6b]
Updated dependencies [bef61fb]
Updated dependencies [b484057]
Updated dependencies [972634d]
@hyperdx/app@2.39.0
Minor Changes
e31e5d8: Offer dashboard tile alerts for Terraform import.
clickhouse_clickstack_alertgained
source = "tile"withdashboard_id/tile_idin provider 3.28.0, sothe bulk export and the per-alert menu now include tile alerts instead of
skipping every alert that is not a saved-search one. A file carrying a tile
alert asks for
>= 3.28.0and explains the hand edit its generated configneeds; an export without one still installs on 3.25.x. A tile alert is withheld
when its tile has a blank or duplicated name — the provider's
tile_idsmap iskeyed by tile name and omits those, so the alert could only be pinned to a
literal id the next dashboard apply can re-mint — or when its dashboard is
provisioned, since ProvisionDashboardsTask rewrites those tiles wholesale. Both
decisions are made server-side, on the import manifest and on the alerts
listing, because neither response carries a dashboard's sibling tile names.
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.
f007c37: Add a context-aware getting-started checklist to the sidebar for recently-created teams. After the setup steps (connect ClickHouse, add data) complete, a second phase tracks product-usage milestones persisted per user on
user.onboardingData: exploring data, building a dashboard, setting up an alert, and using the MCP server. Completion is recorded server-side so it counts from the UI, the external REST API v2, or an MCP tool; the card can be dismissed and reappears if a new task is added to the registry.264f216: feat: Select rows in the search results table to copy or download them
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.
482d2cb: feat: Paginate the alerts page
5311d63: fix: give incident.io webhooks a body incident.io accepts
An incident.io webhook saved without a body was sent the generic
{"text": ...}payload, which has neither of the two fields incident.io requires, so every delivery was rejected and no alert was ever raised. It now gets an incident.io payload carrying a deduplication key that is stable across a firing and its resolve, so incident.io closes the alert it opened, plus the alert id, status, condition and evaluation window inmetadatafor routing. The webhook body editor and its list of template variables are also available when incident.io is the selected service, not only for Generic, so the payload can be tailored to an alert source's configured fields.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.
4db7397: fix: keep a multi-line query visible when the field is not focused
Multi-line SQL fields collapsed to a single line whenever they lost focus, so everything past the first line was hidden until you clicked back into them. Focusing one expanded it into a floating overlay that covered the content underneath — and in a container sized to its content, that overlay left the layout flow and shrank the field to a sliver one character wide.
Any field that allows multiple lines now simply sizes to its content, focused or not, growing the layout rather than floating over it, up to 150px before it scrolls. That covers the search WHERE, SELECT and ORDER BY, the chart editor's SQL fields, and PromQL. Lucene search fields similarly grow up to four lines. Fields with
allowMultiline={false}remain single-line in both SQL and Lucene. The focus overlay is gone rather than made optional, so there is no longer a separate expand-on-focus state to reason about.The language switch beside the search bar stretches to match, with no divider between it and the input. A Lucene bar at the default size also no longer overhangs that switch. The Lucene input reserved a 38px row while drawing a 36px box inside it, so the switch — sized to the 36px the SQL editor uses — stood 2px proud of the input. Both languages now take their height from one shared table, so the seam is flush and the bar does not change height when you switch. Only the default size was affected; the compact bar was already consistent at 30px.
Focus recolors the whole control, including the language switch, without overriding an error or warning border.
84c67f4: fix: show only the delivery time in an alert's notification duration
The notification duration on an alert's evaluation list was timing everything an alert does once it decides to fire: building the message title and links, querying the log lines that go in the body, rendering the template, and then delivering it. That made the column read in seconds while the webhook underneath it answered in milliseconds — the column and its own per-target breakdown disagreed, and the figure was dominated by work that has nothing to do with how fast the notification target responded. It now times the delivery alone. Evaluations already recorded keep their old figure and will read high.
c98be91: Escape source table/database names in the onboarding checklist's has-data probe to prevent SQL injection via a maliciously named data source.
cfacdbe: feat: relative date ranges for dashboards can now be saved
f7ae72c: refactor: Extract PromQL functions, PromqlExpressionEditor, and ChartSeriesControls
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.
b1e48b9: fix: Quote column identifiers when opening row details
78a33ba: feat: Allow configuring dashboard filters as required
db708a8: Color service map nodes by absolute error-rate thresholds instead of scaling
against the worst service on the graph. A service with no errors now renders
neutral grey rather than a pale red, and the remaining nodes fall into three
fixed buckets (under 1%, 1-5%, and 5% or above). A service the map has no error
data for — one that only calls others, with no incoming requests in the window —
renders hollow rather than filled, so "nothing measured" no longer looks like
"nothing wrong".
Previously every node was a shade of red whose intensity was normalized against
the graph-wide maximum, so a map whose worst service sat at 0.3% errors painted
it the same deep red as one at 60%, and a healthy service was indistinguishable
from one with a trace of errors. The legend for error rate now shows the four
discrete steps, marks the 1% and 5% boundaries, and adds a key for the hollow
state. Latency and throughput coloring is unchanged.
bef61fb: feat: Scope tags endpoint by resource type
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 [4d18cb0]
Updated dependencies [c8cc8e5]
Updated dependencies [ff1e77c]
Updated dependencies [482d2cb]
Updated dependencies [e31e5d8]
Updated dependencies [5311d63]
Updated dependencies [96ac6b1]
Updated dependencies [6b39171]
Updated dependencies [84c67f4]
Updated dependencies [f007c37]
Updated dependencies [cfacdbe]
Updated dependencies [806d242]
Updated dependencies [b19fa12]
Updated dependencies [f7ae72c]
Updated dependencies [b217430]
Updated dependencies [b1e48b9]
Updated dependencies [78a33ba]
Updated dependencies [edb693a]
Updated dependencies [0a37198]
Updated dependencies [3876d6b]
Updated dependencies [bef61fb]
Updated dependencies [b484057]
Updated dependencies [6c85ca0]
Updated dependencies [972634d]
@hyperdx/common-utils@0.29.0
Minor Changes
e31e5d8: Offer dashboard tile alerts for Terraform import.
clickhouse_clickstack_alertgained
source = "tile"withdashboard_id/tile_idin provider 3.28.0, sothe bulk export and the per-alert menu now include tile alerts instead of
skipping every alert that is not a saved-search one. A file carrying a tile
alert asks for
>= 3.28.0and explains the hand edit its generated configneeds; an export without one still installs on 3.25.x. A tile alert is withheld
when its tile has a blank or duplicated name — the provider's
tile_idsmap iskeyed by tile name and omits those, so the alert could only be pinned to a
literal id the next dashboard apply can re-mint — or when its dashboard is
provisioned, since ProvisionDashboardsTask rewrites those tiles wholesale. Both
decisions are made server-side, on the import manifest and on the alerts
listing, because neither response carries a dashboard's sibling tile names.
f007c37: Add a context-aware getting-started checklist to the sidebar for recently-created teams. After the setup steps (connect ClickHouse, add data) complete, a second phase tracks product-usage milestones persisted per user on
user.onboardingData: exploring data, building a dashboard, setting up an alert, and using the MCP server. Completion is recorded server-side so it counts from the UI, the external REST API v2, or an MCP tool; the card can be dismissed and reappears if a new task is added to the registry.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
482d2cb: feat: Paginate the alerts page
5311d63: fix: give incident.io webhooks a body incident.io accepts
An incident.io webhook saved without a body was sent the generic
{"text": ...}payload, which has neither of the two fields incident.io requires, so every delivery was rejected and no alert was ever raised. It now gets an incident.io payload carrying a deduplication key that is stable across a firing and its resolve, so incident.io closes the alert it opened, plus the alert id, status, condition and evaluation window inmetadatafor routing. The webhook body editor and its list of template variables are also available when incident.io is the selected service, not only for Generic, so the payload can be tailored to an alert source's configured fields.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.
84c67f4: fix: show only the delivery time in an alert's notification duration
The notification duration on an alert's evaluation list was timing everything an alert does once it decides to fire: building the message title and links, querying the log lines that go in the body, rendering the template, and then delivering it. That made the column read in seconds while the webhook underneath it answered in milliseconds — the column and its own per-target breakdown disagreed, and the figure was dominated by work that has nothing to do with how fast the notification target responded. It now times the delivery alone. Evaluations already recorded keep their old figure and will read high.
cfacdbe: feat: relative date ranges for dashboards can now be saved
806d242: feat: page and filter GET /alerts server-side
f7ae72c: refactor: Extract PromQL functions, PromqlExpressionEditor, and ChartSeriesControls
b1e48b9: fix: Quote column identifiers when opening row details
78a33ba: feat: Allow configuring dashboard filters as required
bef61fb: feat: Scope tags endpoint by resource type
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.