> ## 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.

# RUM alerts

> Alert on the figures the RUM pages show: errors, crash-free sessions, Core Web Vitals, failed requests, new and regressed issues. A rule names an application and a figure, and reads it the way the pages do.

An [alert rule](https://docs.molesignal.com/en-US/alerting) can watch a **RUM figure** in place of a query. The rule names an application, can narrow
it to an environment, a page, and a version, and names one of the figures below. It is evaluated on a schedule against
thresholds, or against the same time on the days before, and it needs no stream and no statement.

The figures are read the way the pages read them, through the same aggregate as the
[overview](https://docs.molesignal.com/en-US/rum) and the [explorer](https://docs.molesignal.com/en-US/rum/explorer.md): a view or a session counts once, in its latest revision, and a
percentile is of the views that have a value. So the number a rule watches is the number the pages show for the same
application, environment, page, and range of time.

## The figures

| Figure | `metric` | What it is | Unit | Rows it needs |
| - | - | - | - | - |
| **Sessions** | `session_count` | Sessions that began in the window. | count | none |
| **Page views** | `view_count` | Page views, or screens in an app, that began in the window. | count | none |
| **Errors** | `error_count` | Errors that happened in the window. | count | none |
| **Error rate (views with an error)** | `error_rate` | Views that met an error, over all views. | percent | 100 views |
| **Crash-free sessions** | `crash_free_sessions` | Sessions without a crash, over all sessions. | percent | 100 sessions |
| **Sessions with frustration** | `frustration_rate` | Sessions that showed a [frustration sign](https://docs.molesignal.com/en-US/rum/frustration.md), over all sessions. | percent | 100 sessions |
| **Failed requests** | `failed_request_rate` | `fetch` and `xhr` requests that got no answer or a 5xx, over all of them. A 4xx is not a failure here. | percent | 200 requests |
| **LCP (p75)** | `lcp_p75` | The 75th percentile of the largest contentful paint. | milliseconds | 50 views that have a value |
| **INP (p75)** | `inp_p75` | The 75th percentile of the interaction to next paint. | milliseconds | 50 views that have a value |
| **CLS (p75)** | `cls_p75` | The 75th percentile of the cumulative layout shift. | score; 0.1 is good | 50 views that have a value |
| **Time to first byte (p75)** | `ttfb_p75` | The 75th percentile of the time to first byte. | milliseconds | 50 views that have a value |
| **New issues** | `new_issues` | [Issues](https://docs.molesignal.com/en-US/rum/errors.md) first seen in the window. | count | none |
| **Regressed issues** | `regressed_issues` | Issues that came back in the window after being resolved. | count | none |

A session or a view belongs to the window in which it **began**. A session that began a minute ago and has not ended counts,
with what it has shown so far, so the newest minutes of a window read a little better than they will once their sessions are
over. A longer window lessens the effect.

### When a figure has no value

A count is a figure even when it is zero, which is how a rule can catch traffic that stopped. Every other figure has **no value**
when the window holds fewer of the rows it needs than the table says: no threshold matches, nothing fires, and an incident
that is open resolves. That keeps a quiet night from firing a rule on a p75 of a handful of views. **Rows needed** in the
rule changes the number for that rule; a count has none.

## Narrow a rule

| Narrowing | Which figures can have it |
| - | - |
| **Environment** | Every figure. |
| **Version** | Every figure but **New issues** and **Regressed issues**: an issue turns up in many versions. |
| **Page** (an app has **Screen**) | Page views, errors, requests, and vitals: **Page views**, **Errors**, **Error rate**, **Failed requests**, and the four vitals. Not the figures of sessions (a session is not on one page) and not the issues. |

The editor offers the environments, pages, and versions the application had over the last day. A page is the path of the URL
with its changing parts grouped, as the pages say it. A name is compared as it is, so a `*` in it is a character.

New and regressed issues are counted by the environment the issue **turned up in**. An issue belongs to the whole
application and keeps the first time it was seen in each environment: an issue first seen in staging last week is new in
production the first time production sees it. Without an environment, an issue is new when the application first saw it.

## Create a rule

Open **Alerts → Alert rules** and choose **New rule**. A **Threshold rule** offers **RUM alert** next to **Metric alert**,
**Log alert**, **Trace alert**, and **APM alert**. Choose the application, narrow it if needed, choose the figure, and the
window the figure is read over: 5 minutes, 15 minutes, or an hour. The editor starts each figure on the window that suits it (a percentile or a share on an
hour) and on a line people commonly page on. Creating a rule requires `alerts.manage`.

**Test rule** draws the figure over the last stretch of time, one point for each window, with the thresholds on it: six hours for
a window of 5 or 15 minutes and twelve hours for a window of an hour. The last point is what the rule would see now. A window with
too few rows has no value and no point. The preview is worked out by the code that evaluates the rule, so what it draws is what
the rule will do.

Choosing another figure starts the thresholds and the window again, because they are in another unit. A figure that cannot be
narrowed to a page or a version says why in the form.

The `alert` role evaluates the rule every `[alert].eval_interval_secs`, 30 seconds by default, over the last window. `for_periods`
counts evaluations in a row that are over the line; a window of minutes already smooths the figure, so the editor starts a RUM rule
at one. See [Create a rule](https://docs.molesignal.com/en-US/api/alerting/create-rule.md#how-a-rule-evaluates).

## Alert from a page

**Alerts** stands at the end of the row that says what a page is of, on the overview, errors, performance, and frustration pages.
A number beside it counts the incidents going on for the application, in the colour of the worst, and is left out when there are
none. The button needs `alerts.read`, and those who do not hold it do not see it.

It opens a drawer with the alerts of the application, in the environment the page is of, or in every environment when the page
is of all of them. The drawer has no application or environment of its own: it follows the page. It reads from the most urgent to
the least.

* **Going on** lists the incidents of the application that are open or acknowledged, the worst first. Each says how bad it is,
  which rule it is, the line the rule pages on, and when it opened. **Open** opens the incident over the page.
* **Rules of this application** lists the rules that watch it, in the environment in front and in every environment, those that
  fire first, with how each stands: **Firing**, **Pending**, **Healthy**, or **Off**. **New rule** opens the rule editor with the
  application and the environment filled in, and **Edit** opens a rule. Both need `alerts.manage`.
* **Templates** lists the rules worth having on the application, ready to create.

The drawer of a row on the [performance page](https://docs.molesignal.com/en-US/rum/performance.md#what-a-value-is-made-of) has **Alert on this**, which opens
the rule editor on the vital of the tab that is open, narrowed to the page or the version of the row.

## Templates

A template is a rule for a figure, with the lines it pages on and the window it is read over. **Create** makes the rule at once:
enabled, `scheduled`, with the template's lines as its severities, `for_periods` 1, the default escalation policy, and the
labels a rule made in the editor has, with `rum.template` for the template. It is named after the application, the environment,
and the template: `Storefront · prod · Slow page loads`. Change anything about it afterwards in **Alerts → Alert rules**. Creating
a rule needs `alerts.manage`; without it the button is off and says why.

A template that was made for the application and the environment of the page shows **Created and enabled** and a link to its rule in place
of the button, so that it is not made twice. It can be made again for another environment, and one made for every environment is
not the one of a single environment.

Each card says what the figure is **Now**, over the window of the template, read by the same code that evaluates the rule. A
Core Web Vital also says how the value grades. When a rule made from the template would fire at once, the card says so. A figure
with too few rows has no value, and the card says how many it waits for.

The lines of the Core Web Vitals are the grades web.dev gives for good and poor.

| Template | Figure | Lines | Window |
| - | - | - | - |
| **Slow page loads**, recommended | LCP (p75) | Warning above 2.5 s, critical above 4 s | 1 hour |
| **Slow interactions**, recommended | INP (p75) | Warning above 200 ms, critical above 500 ms | 1 hour |
| **Page errors**, recommended | Error rate | Warning above 2%, critical above 5% | 15 minutes |
| **Failed requests**, recommended | Failed requests | Warning above 2%, critical above 5% | 15 minutes |
| **New issues**, recommended | New issues | Warning above 0 | 15 minutes |
| **Layout shifts** | CLS (p75) | Warning above 0.1, critical above 0.25 | 1 hour |
| **Frustrated sessions** | Sessions with frustration | Warning above 3%, critical above 8% | 1 hour |
| **Regressed issues** | Regressed issues | Critical above 0 | 15 minutes |
| **Traffic stopped**, optional | Sessions | Critical below 1 | 15 minutes |

An app has seven, and crashes stand where the web vitals are. **Screen errors** is the error rate of the screens.

| Template | Figure | Lines | Window |
| - | - | - | - |
| **More crashes**, recommended | Crash-free sessions | Warning below 99.5%, critical below 99% | 1 hour |
| **Screen errors**, recommended | Error rate | Warning above 2%, critical above 5% | 15 minutes |
| **Failed requests**, recommended | Failed requests | Warning above 2%, critical above 5% | 15 minutes |
| **New issues**, recommended | New issues | Warning above 0 | 15 minutes |
| **Frustrated sessions** | Sessions with frustration | Warning above 3%, critical above 8% | 1 hour |
| **Regressed issues** | Regressed issues | Critical above 0 | 15 minutes |
| **Traffic stopped**, optional | Sessions | Critical below 1 | 15 minutes |

**Traffic stopped** pages when the window holds no session, so it is not for an application that is quiet at night.

## Anomaly rules

An **Anomaly detection rule** offers **RUM figure** as a source. It compares the figure of the last window with the same window
on each of the days before, with the baselines and settings of [any anomaly rule](https://docs.molesignal.com/en-US/alerting). It offers every figure but
**New issues** and **Regressed issues**, which have no usual level.

## Incidents

A rule made in the editor carries the labels `rum.application`, and `deployment.environment`, `rum.page`, and `rum.version` for
what it narrows to, and its incidents copy them. When an incident opens, it also keeps up to three **sample sessions** that show the
figure at its worst, each with the session ID, the time, the value the session had, and what went with it: the views with the
worst value of a vital and the element behind it, the newest errors and their messages, the sessions with a crash or a
frustration sign, the failed requests and their paths. For new and regressed issues they are the sessions of the newest errors of
those issues. The figures of traffic have no samples.

The incident drawer, opened from **Going on**, from **Alerts → Incidents**, or from a link, shows them as **Sample sessions**: when
it happened, who it was (a name, an address, an ID, or the ID the SDK keeps of a visitor who never signed in), the browser and
the system, and what made it a sample. **Replay** opens the session five seconds before that moment when it was recorded, and **Session**
opens the page of a session that was not. Who they were, and whether they were recorded, is read from the sessions and needs
`streams.query`; without it the rows still say when and why.

**Open in RUM** goes to the page that tells the figure, of the same application, environment, and page, over the time of the
incident: from before the window the rule reads to a little after it was resolved, or to now while it is going on.

| Figure | Opens |
| - | - |
| A vital | [Performance](https://docs.molesignal.com/en-US/rum/performance.md), on the vital, and in the drawer of the page when the rule names one |
| Failed requests | [Resources](https://docs.molesignal.com/en-US/rum/performance.md#resources) |
| Errors, error rate, new and regressed issues, crash-free sessions | [Errors](https://docs.molesignal.com/en-US/rum/errors.md) |
| Sessions with frustration | [Frustration](https://docs.molesignal.com/en-US/rum/frustration.md) |
| Sessions, page views | [Overview](https://docs.molesignal.com/en-US/rum) |

## The rule in the API

A rule on a RUM figure has `query.rum` in place of the statement and the stream of `query`. [Create a
rule](https://docs.molesignal.com/en-US/api/alerting/create-rule.md) with it.

```json theme={null}
{
  "name": "Storefront checkout is slow",
  "kind": "scheduled",
  "query": {
    "language": "sql",
    "statement": "",
    "period_secs": 3600,
    "rum": {
      "application_id": "storefront",
      "environment": "prod",
      "page": "/checkout",
      "metric": "lcp_p75"
    }
  },
  "trigger": { "operator": "gt", "threshold": 2500, "for_periods": 1, "silence_secs": 300 },
  "thresholds": [
    { "severity": "warning", "operator": "gt", "threshold": 2500, "for_periods": 1 },
    { "severity": "critical", "operator": "gt", "threshold": 4000, "for_periods": 1 }
  ],
  "labels": { "rum.application": "storefront", "deployment.environment": "prod", "rum.page": "/checkout" },
  "annotations": {}
}
```

`period_secs` is the window, from 60 seconds to 6 hours. The application has to exist, and `page` and `version` are refused for
the figures that cannot have them. `min_samples` is optional, and refused for a count. Thresholds are in the unit of the figure.

The RUM pages find the incidents of an application by the label `rum.application` (and by `deployment.environment`, when the page is
of one environment), and the rules of an application by their `query.rum`. A rule made through the API carries the labels it is given,
so give it these to have its incidents counted and listed on the pages. A rule made from a template adds `rum.template`, which is
how a card knows its template was made.

`POST /api/v1/rum/alerts/preview` is what **Test rule** reads. See [the RUM API](https://docs.molesignal.com/en-US/api/rum.md#preview-an-alert-rule).

## Permissions

* `alerts.read` shows **Alerts** on the RUM pages, with the incidents, the rules, and the templates in its drawer.
* `alerts.manage` creates a rule: from a template, with **New rule**, or in the rule editor, and opens **Edit** on a rule.
* `streams.query`, the permission that reads the rest of RUM, reads the preview and what the templates say the figures are now,
  and who the sample sessions of an incident were.

See [RUM](https://docs.molesignal.com/en-US/rum#permissions).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.