Skip to content

PromQL label lookups fail on TimeSeries tables created by ClickHouse 26.10 (schema version 8) #3580

Closed

Description

@bcanvural

What happened?

On ClickHouse 26.10, every PromQL dashboard variable (PROMETHEUS_LABEL filter) with a match selector shows:

match[] requires a TimeSeries table created with store_min_time_and_max_time = 1

The same lookup without match runs, but ignores the dashboard's time range and reads every series the table has ever seen.

Why: ClickHouse 26.10 creates TimeSeries tables of schema version 8 by default. Version 8 moved min_time and max_time out of the tags table into a separate time ranges inner table (timeSeriesTimeRanges(db, table), enabled by store_time_ranges, on by default). From the engine docs: "The columns min_time and max_time were moved from the tags table to the new optional time ranges table", and store_min_time_and_max_time "applies to tables of version 7 or earlier only".

getSeriesFilterConditions in packages/api/src/controllers/timeseriesEngine.ts looks for the two columns only in the tags table. On a version 8 table it doesn't find them, so it rejects match[] and drops the time bounds.

Impact on a production-sized table: with about 13 M series (tags inner table about 38 M rows, 25 GiB uncompressed) and a 20 GiB per-query read limit, every dashboard variable lookup fails: it reads the whole tags table and stops with "Limit for rows or bytes to read exceeded, max bytes: 20.00 GiB". The same lookup with a metric selector (match[]=up, 1-hour window) reads 1.5 GB in 1.6 s, but on version 8 tables HyperDX rejects match[]. The time window alone helps little there: half of the series had samples in the last hour, so most of the tags table is still read.

ClickHouse's own /prometheus/api/v1/label/<name>/values?match[]=… answers the same lookup correctly on these tables, and timeSeriesSelector() works on them (it prunes on the time ranges table).

Steps to reproduce

Reproduces on play.hyperdx.io? No: it needs a TimeSeries table created by ClickHouse 26.10.

  1. On ClickHouse 26.10.3.7:
    SET allow_experimental_time_series_table = 1;
    CREATE TABLE default.ts ENGINE = TimeSeries;          -- version 8
    DESCRIBE timeSeriesTags(default, ts);                 -- id, metric_name, tags: no min_time/max_time
    DESCRIBE timeSeriesTimeRanges(default, ts);           -- id, min_time, max_time
  2. Point a PromQL source at default.ts.
  3. Add a dashboard variable with a match selector: the warning above. Or call GET /api/prometheus/label/job/values?sourceId=…&match[]=up.

Also affected: the int test fixture seedTimeSeriesTagsTable creates ENGINE = TimeSeries and inserts min_time/max_time into the tags table, so the TimeSeries suites fail on 26.10 (CI runs 26.8.36.3, where tables are of the old layout and version isn't a known setting).

How are you running HyperDX?

Self-hosted, and a local dev stack on main (78143c8), with ClickHouse 26.10.3.7.

Where does it show up?

The API (/api/prometheus/labels, /api/prometheus/label/:name/values), and in the UI as the warning on PromQL dashboard variables and in label autocomplete.

Debug info

N/A (API).

Logs

The match[] error above, and on the large table: Limit for rows or bytes to read exceeded, max bytes: 20.00 GiB.

Proposed fix

I have a fix with tests and can open a PR: read the time ranges table when the tags table has no bounds. match[] keeps using timeSeriesSelector(); start/end without a selector filter through id IN (SELECT id FROM timeSeriesTimeRanges(...) GROUP BY id HAVING min(min_time) <= end AND max(max_time) >= start). Version 7 tables behave as before.

Activity

  1. added a commit that references this issue on Nov 9, 2026
    b1d4e60
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions