> ## Documentation Index
> Fetch the complete documentation index at: https://docs.molesignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# PromQL support matrix

> The PromQL functions, operators, and modifiers MoleSignal's engine supports, and the known gaps.

MoleSignal runs PromQL over metric streams with a built-in evaluator (`promql-parser` plus an
Arrow/DataFusion evaluator). Both **instant** and **range** queries are supported — a range query
steps through `[start, end]` and returns a matrix. This page is the authoritative support matrix.

## Supported

### Range-vector functions (`metric[range]`)

`rate`, `irate`, `increase`, `delta`, `idelta`, `deriv`, `predict_linear`, `resets`, `changes`,
`holt_winters` (alias `double_exponential_smoothing`), and the full `*_over_time` family:
`avg_over_time` / `min_over_time` / `max_over_time` / `sum_over_time` / `count_over_time` /
`quantile_over_time` / `stddev_over_time` / `stdvar_over_time` / `last_over_time` /
`present_over_time` / `mad_over_time`.

### Aggregations (with `by()` / `without()`)

`sum`, `avg`, `min`, `max`, `count`, `stddev`, `stdvar`, `quantile`, `group`, `count_values`,
`topk`, `bottomk`, `limitk`, `limit_ratio`.

### Histograms

`histogram_quantile(q, sum by(le)(rate(metric_bucket[range])))` — linear interpolation over classic
`le` buckets.

`histogram_fraction(lower, upper, v)` — over classic `le` buckets, estimates the fraction of
observations that fall within `[lower, upper]` (same piecewise-linear CDF,
`(rank(upper) - rank(lower)) / total`).

### Labels & sorting

`label_replace`, `label_join`, `sort`, `sort_desc`, `sort_by_label`, `sort_by_label_desc`.

### Time

`time`, `timestamp`, `minute`, `hour`, `day_of_week`, `day_of_month`, `day_of_year`,
`days_in_month`, `month`, `year` (UTC; the date functions default to `vector(time())`).

### Type / absence

`vector`, `scalar`, `absent`, `absent_over_time`.

### Math / rounding / trig

`abs`, `ceil`, `floor`, `round`, `exp`, `ln`, `log2`, `log10`, `sqrt`, `sgn`,
`clamp` / `clamp_min` / `clamp_max`, `sin` / `cos` / `tan` / `asin` / `acos` / `atan` / `sinh` /
`cosh` / `tanh` / `asinh` / `acosh` / `atanh`, `pi`, `deg`, `rad`.

### Operators

Arithmetic `+ - * / % ^`, comparison `== != > < >= <=` (with `bool`), the set operators
`and` / `or` / `unless`, vector matching `on(...)` / `ignoring(...)` with
`group_left` / `group_right`, and unary negation.

### Modifiers & structure

Selector `@` (`start()` / `end()` / `<ts>`) and `offset` (including on matrix selectors);
subqueries `inner[range:step]`.

## Not implemented / known differences

| Feature                                                                                                                    | Status  | Notes                                                                                                                      |
| -------------------------------------------------------------------------------------------------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------- |
| Native-histogram functions `histogram_count` / `histogram_sum` / `histogram_avg` / `histogram_stddev` / `histogram_stdvar` | ❌ → 400 | N/A for the classic `le`-bucket model; use `histogram_quantile` for quantiles and `histogram_fraction` for interval shares |
| Binary `default` fill-in                                                                                                   | ❌ → 400 | —                                                                                                                          |
| Subqueries inside a range query                                                                                            | ⚠️      | fall back to instant evaluation (no outer × inner double stepping); instant / alerting paths are exact                     |
| `timestamp()`                                                                                                              | ⚠️      | returns the eval time on the instant path, the point's own timestamp on the range path                                     |
| Scalar function params (`predict_linear` `t`, `holt_winters` `sf`/`tf`, quantiles)                                         | ⚠️      | numeric literals only                                                                                                      |

Unsupported functions / syntax return `Error::Invalid("promql function not yet supported: <name>")`,
which `POST /api/v1/query` (`language: "promql"`) maps to `400`.

<Note>
  Recording and alerting rules do **not** go through PromQL. These rules use the MoleSignal `AlertRule`
  model, which is not interoperable with the Prometheus rule format. See [Alerting](/en-US/alerting).
</Note>

## Label matching

`=`, `!=`, `=~`, `!~` (regex via RE2 — slightly different from Prometheus PCRE). `__name__` is fixed
to the metric stream name and cannot be renamed.

## Internal data layout

A metric stream's schema keeps labels as **separate columns** (not a JSON blob):

```sql theme={null}
_timestamp  Timestamp(Microsecond)  NOT NULL   -- time
value       Float64                 NOT NULL   -- the measurement (Int64 etc. is accepted and cast to f64)
<label_x>   Utf8 …                             -- every non-reserved column is a label
```

The engine reads parquet directly for the candidate `FileMeta` time ranges (`batches_to_series`)
and builds `(labels, samples)` series, applying matchers (`=`/`!=`/`=~`/`!~`) in code; `@` / `offset`
resolve to the effective evaluation instant in `load_matrix`.
