skip to content

Why would you add a Prometheus recording rule, and what does its rule group's interval control?

level: middleimportance: should knowfreq 54%

answer

  1. Compute once instead of on every query
  2. The result becomes a real series
  3. Scheduling belongs to the group, not the rule
  4. Order matters inside a group only
  5. Colons in the name are a convention

basics

~20 s

A Prometheus recording rule evaluates an expression on a schedule and saves the result as a new series, so dashboards and alerts read one cheap series instead of recomputing. The group's interval sets how often every rule in it runs.

solid answer

~50 s

A recording rule has `record` (the new series name) and `expr`. Prometheus evaluates it on the group's schedule and writes the result back into the store, so an expensive aggregation is computed once rather than by every dashboard panel and alerting rule that needs it. That matters most for expressions that fan across a large store, and for long-range queries that would otherwise touch millions of samples. Rules live inside groups: a group's `interval` overrides the global `evaluation_interval` for every rule in it, and rules **inside one group run sequentially in file order**, so a later rule can safely consume an earlier rule's output. Across groups there is no ordering guarantee. The conventional name is `level:metric:operations` — for example `job:gym_checkins:rate5m` — and the colons are reserved for recorded series so they never collide with instrumented metric names.

code

yaml · 8 lines
yaml
groups:
  - name: membership-recording
    interval: 30s
    rules:
      - record: job:gym_checkins:rate5m
        expr: sum by (job) (rate(gym_checkins_total[5m]))
      - record: job:gym_checkins_failed:ratio_rate5m
        expr: sum by (job) (rate(gym_checkins_failed_total[5m])) / job:gym_checkins:rate5m

go deeper

for a junior

Know that a recording rule saves a query's result as a new series on a schedule, and that its two fields are the new series name and the expression. Recognise a colon in a series name as the recorded-series convention.

for a middle

Explain the group as the unit of scheduling: its interval overrides the global evaluation interval, and rules inside it run sequentially so a later rule can consume an earlier one's output. Give a concrete reason to precompute.

for a senior

Show you have operated a large rule set — groups falling behind their interval and leaving gaps, chained rules split across groups reading stale values, aggregation dropping the label an alert needed, and the series-count cost of recording everything.

for a principal

Decide the estate-wide policy: which aggregates are recorded centrally versus by each team, what naming and label conventions are mandatory, and how you stop a rule set growing until evaluation cost rivals the query cost it was meant to remove.

A recording rule is the other half of Prometheus's rule engine. It shares the file format and the evaluation loop with alerting rules, but instead of producing an alert it produces a **new time series** that is written back into the store. ## The shape of a recording rule A recording rule has exactly two required fields, plus optional labels: ```yaml groups: - name: membership-recording interval: 30s rules: - record: job:gym_checkins:rate5m expr: sum by (job) (rate(gym_checkins_total[5m])) ``` At every evaluation Prometheus runs `expr`, takes each sample in the result, renames it to the value of `record`, keeps the result's labels (plus any `labels` you add on the rule), and appends it at the evaluation timestamp. From then on `job:gym_checkins:rate5m` is an ordinary series that any query, dashboard or alerting rule can select. ## Why precompute at all Three reasons, in descending order of how often they actually decide it: 1. **Query cost.** An aggregation that fans across a 2.3-million-series store is expensive every single time it runs. On a membership platform where one team's services generate roughly seventy per cent of the series, their team dashboard alone can re-run the same heavy aggregation from a dozen panels on every refresh. A recording rule collapses all of that into one evaluation per interval. 2. **Long ranges.** A query over thirty days against raw series has to read every sample in the range. Against a pre-aggregated series recorded every 30 seconds it reads orders of magnitude fewer points, which is often the difference between a dashboard that loads and one that times out. 3. **One definition, many consumers.** When the dashboard panel, the alerting rule and the weekly report each re-type the same expression, they drift. Recording the expression once makes the alert and the graph provably the same number. ## Groups: interval and ordering Every rule sits inside a group, and the group — not the individual rule — is the unit of scheduling: | Setting | Scope | What it does | |---|---|---| | `evaluation_interval` (global) | whole server | Default cadence for every group that does not override it | | `interval` (per group) | one group | Overrides the global cadence for all rules in that group | | file order within a group | one group | Rules evaluate **sequentially**, top to bottom | Two consequences follow, and interviewers ask about both. **Ordering is a real guarantee inside a group and a real hazard across groups.** Because rules in a group run one after another against the same evaluation, a rule can reference a series produced by an earlier rule in the *same* group and get this cycle's value. Put those two rules in different groups and you lose that: groups are scheduled independently, so the dependent rule reads whatever the previous cycle happened to leave behind, or nothing at all when the store is fresh. Chained recording rules therefore belong in one group, in dependency order. **A group that cannot finish within its interval falls behind.** Sequential evaluation means the group's total runtime is the sum of its rules. If that exceeds `interval`, evaluations start late and eventually get skipped, and your recorded series develops gaps that look like an outage. Prometheus exposes per-group metrics for the last evaluation duration and for missed iterations; those are the numbers to watch when a rule set grows. The fixes are to split the group so independent rules run in parallel groups, to lengthen that group's `interval`, or to make the expensive expression cheaper. ## Naming, and the traps The documented convention is `level:metric:operations`: - **level** — the aggregation level, usually the labels that survive, such as `job` or `cluster`. - **metric** — the metric name being aggregated. - **operations** — the operations applied, most recent first, such as `rate5m` or `sum`. Colons appear only in recorded series names — instrumented metric names never use them — so a colon in a series name is an immediate signal that you are looking at a rule output rather than something an application exposed. Keeping to the convention also means a reader can tell from the name alone which labels are still present, which matters when an alert built on a recorded series can no longer identify the failing instance because the recording rule aggregated `instance` away. Two further traps: - **There is no backfill.** A recorded series exists only from the moment the rule was loaded. Adding a rule today and then asking for last quarter's numbers returns nothing, so create the rules that feed a long-horizon report well before you need the report. - **Recorded series cost storage.** Each one is a new series in the same store you were trying to protect. Recording every intermediate step of an expression multiplies series count; record the aggregates that are actually reused.

  • Why must two chained recording rules live in the same group rather than in two groups?
    Rules inside a group evaluate sequentially in file order, so the second rule sees the series the first one just wrote at this evaluation. Groups are scheduled independently of each other, so splitting the pair means the dependent rule reads a stale value from some earlier cycle, or nothing at all shortly after startup. Order within a group is the only ordering Prometheus guarantees.
  • A recording rule group's evaluations start arriving late and then skipping. What is happening?
    The group's rules run one after another, so the group's total runtime is the sum of them. Once that exceeds the group's `interval` the next evaluation cannot start on time, and the recorded series develop gaps. Watch the per-group evaluation-duration metric, then split independent rules into separate groups, lengthen that group's interval, or cheapen the expression.
  • You add a recording rule today and query it over the last quarter. What comes back?
    Nothing before the moment the rule was loaded. Prometheus evaluates rules forward in time and does not retroactively compute a recorded series over history, so the series simply begins when the rule did. If a long-horizon report will need an aggregate, the rule has to exist well before the report does.

saying these in an interview costs you the question

  • Thinks a recording rule can fire an alert
  • Believes recorded series are backfilled over history
  • Assumes rules across different groups evaluate in order
  • Says recording rules make the stored data smaller
  • Cannot say what the group interval overrides