Metric Temporality
5 minute read
Overview
Temporality describes how metric values relate to time. Understanding temporality is essential for:
- Choosing the correct aggregation function (sum vs last)
- Ensuring compatibility with downstream destinations
- Avoiding double-counting errors that corrupt your data
Metrics report data over time in two fundamentally different ways: delta and cumulative.
Delta vs cumulative
Delta temporality
Delta metrics report the change since the last measurement. Each value represents only what happened during that interval.
| Timestamp | Value | Meaning |
|---|---|---|
| T1 | +5 | 5 new requests |
| T2 | +3 | 3 more requests |
| T3 | +7 | 7 more requests |
Safe aggregation: sum - Add delta values to get the total (5 + 3 + 7 = 15)
Cumulative temporality
Cumulative metrics report the running total since process start. Each value includes all previous values.
| Timestamp | Value | Meaning |
|---|---|---|
| T1 | 5 | Total is now 5 |
| T2 | 8 | Total is now 8 |
| T3 | 15 | Total is now 15 |
Safe aggregation: last - Take the most recent value (15)
The double-counting mistake
Summing cumulative metrics produces incorrect results:
Cumulative values: 5 + 8 + 15 = 28 (WRONG - double counted)
Actual total: 15 (CORRECT)
This is a common source of data corruption when pipelines aggregate metrics without considering temporality.
Monotonic vs non-monotonic
Beyond temporality, metrics have a monotonicity property:
| Type | Behavior | Examples |
|---|---|---|
| Monotonic | Value only increases (or resets to 0) | requests_total, bytes_sent, errors_count |
| Non-monotonic | Value can go up or down | memory_used, active_connections, queue_depth |
Monotonic metrics are typically counters. Non-monotonic metrics are typically gauges.
Edge Delta uses is_monotonic as part of metric identity. Metrics with different monotonicity are kept in separate aggregation buckets automatically.
OpenTelemetry metric types and temporality
| OTel Metric Type | Supports Temporality | Default SDK Temporality | Notes |
|---|---|---|---|
Sum | Yes (is_monotonic: true/false) | Cumulative | Counters and UpDownCounters |
Histogram | Yes | Cumulative | Bucket counts have temporality |
ExponentialHistogram | Yes | Cumulative | Scale/bucket structure + temporality |
Gauge | No | N/A | Point-in-time values only |
Summary | No (deprecated) | N/A | Legacy Prometheus type |
The OpenTelemetry SDK defaults to cumulative temporality. To configure delta output:
OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=delta
Destination requirements
Different OTLP receivers have different temporality requirements:
- Some destinations accept only delta metrics and reject cumulative
- Some destinations accept only cumulative metrics
- Some destinations accept both and handle conversion internally
Check your destination’s documentation for specific requirements. If your destination rejects cumulative metrics, use the Cumulative to Delta processor to convert before sending.
Aggregation best practices
Choose aggregation functions based on metric type and temporality:
| Metric Type | Temporality | Recommended Aggregation | Why |
|---|---|---|---|
| Counter | Delta | sum | Add up changes safely |
| Counter | Cumulative | last or convert first | Take latest value, or use cumulative_to_delta |
| Gauge | N/A | avg, min, max, last | Represents current state, not additive |
| Histogram | Delta | sum on counts | Bucket counts are additive |
| Histogram | Cumulative | Convert first, then sum | Need delta conversion for safe aggregation |
How Edge Delta handles temporality
The Aggregate Metric processor automatically separates metrics by temporality. Two metrics with the same name but different temporalities are aggregated in separate buckets:
# Metrics with different temporalities stay separate
http.requests (delta) → aggregated separately
http.requests (cumulative) → aggregated separately
The aggregation key includes:
- Metric name
- Aggregation temporality (delta or cumulative)
- Monotonicity flag (true or false)
This prevents accidental mixing that would corrupt aggregation results.
Converting cumulative to delta
When your source emits cumulative metrics but your destination requires delta, use the Cumulative to Delta processor:
- name: convert
type: cumulative_to_delta
data_types:
- metric
Behavior notes:
- The first data point in a series is emitted as-is (no previous value exists)
- Counter resets (where the new value is lower than previous) are handled automatically
- Gauge metrics pass through unchanged
Example: Mixed temporality pipeline
When your sources emit both cumulative and delta metrics, route them appropriately before aggregation.
Route processor: Evaluate metric.sum.aggregation_temporality to separate cumulative metrics. Delta metrics and gauges pass through to aggregation directly:
paths:
- path: cumulative
condition: metric.sum.aggregation_temporality == "cumulative"
# Delta metrics and gauges go to unmatched path
Cumulative to Delta processor: Convert cumulative sum metrics to delta format so they can be safely aggregated with sum. The first data point for each series is dropped (no previous value to diff):
data_types:
- metric
Aggregate Metric processor: With all metrics now in delta format, safely aggregate using sum. Group by dimensions like service.name and http.method:
aggregation_type: sum
interval: 60s
group_by: [service.name, http.method, http.status_code]
keep_only_group_by_keys: true
Quick reference
Delta metrics:
- Safe to sum across time windows
- Safe to sum across instances
- May lose data on process restart
- Common sources: OTLP exporters, StatsD
Cumulative metrics:
- Do not sum directly
- Use
lastor convert to delta first - Survives scrape gaps
- Common sources: Prometheus, OpenMetrics
Edge Delta behavior:
- Automatically separates by temporality
- Preserves
is_monotonicflag - Use
cumulative_to_deltaprocessor for conversion - First point dropped during conversion (no previous value to diff)
See also
- Cumulative to Delta Processor - Convert cumulative metrics to delta format
- Aggregate Metric Processor - Group and summarize metrics
- Metric Cardinality - Understand how attributes create timeseries
- OTLP Destination - Send metrics via OTLP