Skip to content

Cardinality & cost rules

Telemetry cost is mostly cardinality, and cardinality is mostly one label somebody added without thinking. This tab is where you find it, cut it, and then prove the cut worked.

Every record that enters the pipeline is metered with a signal (logs, metrics, traces), a verdict, and its real byte count.

The verdict is binary: kept, or not. Everything not kept is the saving — measured in bytes that were actually going to be stored, not estimated from a rule’s stated intent.

Crucially, usage is also attributed per rule. Each rule carries a stable key, and the meter records records and bytes against it. So the question “is this rule earning its keep?” has a number, not an opinion.

The panel shows totals by signal and verdict, a time series, per-rule attribution, and a log severity mix.

Before writing a rule, look at:

  • Cardinality by metric and by label — the series count each is responsible for, ranked. The top of that list is usually a request id, a pod name, a user id, or a full URL path that became a label.
  • Log severity mix — DEBUG shipped to production storage is the single most common unnecessary cost.
  • Per-rule attribution — what your existing rules are already saving.

A label with 50,000 distinct values is not a label. It is a field, and it belongs in the log body or a span attribute, not in a metric’s identity.

Four modes, in increasing order of how much you keep:

Mode What it does Use when
drop_log Discard matching lines entirely. The line has no diagnostic value at any volume.
sample_log Keep a percentage of matching lines. The line is useful in aggregate but not every instance.
dedupe_log Collapse repeats that share the chosen fields. A retry loop or crash loop emitting the same line thousands of times.
drop_attributes Keep the line, drop named attributes. The line matters; one fat attribute is the cost.
Field Purpose
env Scope to an environment — cut hard in dev, gently in prod.
servicePattern Which services this applies to.
bodyContains Substring match on the log body.
filterQuery A full log search query — the same grammar as the search bar.
severityMax Only affect records at or below this severity. The safety catch: set it so a rule can never eat your errors.
sampleRate For sample_log.
dedupeFields For dedupe_log — which fields define “the same line”.
dropAttributes For drop_attributes — the attribute names to strip.
enabled Rules can exist without being armed.
effectiveFrom When it starts applying.

filterQuery is the powerful one: because it is the same grammar as log search, you can find the noise in the Logs tab first, confirm the query matches exactly what you think, and then paste it into a rule.

Simpler shape: env, metricPattern, mode, and labels. Point them at the metric names and the specific labels the cardinality view showed you at the top of the list.

Parsing turns an unstructured line into searchable fields, which is what lets you write a precise filterQuery instead of a broad bodyContains. Two types:

  • json — the body is JSON; fields are extracted directly.
  • grok — a pattern extracts named fields.

You do not write grok by hand. Paste one real log line and Runtimez generates the pattern from it, showing the detected segments as chips you can rename, toggle, or add to. The pattern it produces is what gets compiled.

Parse first, then reduce. A parsed field makes a narrow rule possible; without it you are matching on substrings and hoping.

Redact values before they are stored. Each rule pairs a matcher with a validator and an action, and custom rules can carry an internal ticket id so an exception has an owner and a paper trail.

This is not a cost feature — it is a compliance one — but it lives here because it operates at the same point in the pipeline, and both answer “what actually gets written down”.

  1. Find it in the Logs tab. Build the query there until it matches exactly the lines you mean.
  2. Check the volume it claims. A rule that matches more than you expected is the failure mode that hurts.
  3. Set severityMax. Almost every log rule should be incapable of touching WARN and above.
  4. Prefer the weakest mode that works — drop_attributes over sample_log, sample_log over drop_log.
  5. Scope by env first. Prove it in dev.
  6. Create it disabled, then arm it.
  7. Come back and read its per-rule attribution. If it saved nothing, delete it — a rule that does not pay for itself is a query you cannot run for no reason.

The left rail’s Usage & Savings page rolls the same meter up across signals against your plan’s allowances, over 24h and 30d, alongside your plan, cluster count and retention.

Retention is worth understanding as a cost lever in its own right: it multiplies whatever you keep. Cutting retention and cutting ingest are different decisions with different consequences — shorter retention loses history uniformly, while a reduction rule loses one category of data completely but keeps the rest for the full window.

Traces have their own mechanism, because a trace is a tree rather than a line — see Trace sampling. The two work together: sampling shapes trace volume, reduction rules shape logs and metrics, and both report into the same meter.