- Prometheus: https://prometheus.io/
- PromQL basics: https://prometheus.io/docs/prometheus/latest/querying/basics/
- Grafana: https://grafana.com/

- You define recording rules in one or more rule files (YAML).
- Prometheus evaluates the rule expressions at a configured interval and writes the results to the TSDB as new metrics.
- Dashboards and queries can then read those recorded metrics by name instead of recalculating expensive expressions.
Configure rule file loading
Inprometheus.yml you point Prometheus to one or more rule files using the rule_files section. Globs are supported, so you can load all files from a directory.
Example minimal configuration (note rule_files must list the file(s) or glob patterns to load):
If you change rule files, Prometheus needs to reload its configuration. You can either restart the service or trigger a reload using the HTTP endpoint (
POST /-/reload) or SIGHUP. Reloading avoids a full restart.Rule file structure
A rule file contains one or more rule groups under thegroups: key. Each group can define an interval (overrides global evaluation interval for that group) and a list of rules. Each rule has:
record: name for the resulting time seriesexpr: the PromQL expression to evaluatelabels(optional): to add/remove labels on the recorded series
Parallel/Sequential evaluation model
- Each rule group is evaluated in parallel with other groups.
- Within a group, rules are evaluated sequentially in the order listed. This allows later rules to reference earlier recorded rules in the same group.

Because rules inside a group run sequentially, any rule that references another rule must come after the rule it references. Otherwise the referenced recorded series may not exist yet.
Useful example expressions
Calculate percent memory free on a node:Example recording rules
Create/etc/prometheus/rules.yml (or any file you reference from rule_files) with a group that runs every 15s and records the two metrics above:
Chaining rules (reference recorded metrics)
Because rules in a group run sequentially, you can reference a recorded metric in a subsequent rule. Example:node_filesystem_free_percent_avg aggregates the recorded node_filesystem_free_percent metric. Because it appears after the recorded metric in the same group, the reference will resolve correctly.
Naming best practices for recording rules
Use a structured naming scheme composed of three parts separated by colons (or another consistent delimiter):- level — aggregation level (labels retained), typically includes
jobplus any target labels - metric — the base metric name
- operation — aggregators/functions applied (e.g.,
rate_5m,sum,avg)
job:method:path:http_errors:rate_5m (or a compact variant like job_method_path_http_errors_rate_5m depending on your conventions).

method and path and you want a 5m rate aggregated by job, method, path:
- Aggregation level:
job,method,path - Metric name:
http_errors_total - Operation:
rate_5m
job_method_path_http_errors_rate_5m
If you remove path from aggregation, change the level accordingly (e.g., job,method).
Best practice: group all rules for a particular scrape job into a single rule group. That keeps related metrics together and ensures consistent evaluation intervals.
Example grouping by job:
Add rules to Prometheus and reload
- Create or edit rule file (example):
- Ensure
prometheus.ymlcontains the rule file path (or glob) underrule_files:
- Reload Prometheus configuration:
- Reload via HTTP API:
- Or restart service:
Verify rules
Open the Prometheus UI:- Go to Status → Rules
- Confirm rules are
OKand evaluate at the expected interval - You can also query the recorded metric names in the expression browser to see current values.