Metric Temporality

Understand delta vs cumulative temporality and how it affects metric aggregation, destination compatibility, and pipeline design.

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.

TimestampValueMeaning
T1+55 new requests
T2+33 more requests
T3+77 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.

TimestampValueMeaning
T15Total is now 5
T28Total is now 8
T315Total 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:

TypeBehaviorExamples
MonotonicValue only increases (or resets to 0)requests_total, bytes_sent, errors_count
Non-monotonicValue can go up or downmemory_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 TypeSupports TemporalityDefault SDK TemporalityNotes
SumYes (is_monotonic: true/false)CumulativeCounters and UpDownCounters
HistogramYesCumulativeBucket counts have temporality
ExponentialHistogramYesCumulativeScale/bucket structure + temporality
GaugeNoN/APoint-in-time values only
SummaryNo (deprecated)N/ALegacy 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 TypeTemporalityRecommended AggregationWhy
CounterDeltasumAdd up changes safely
CounterCumulativelast or convert firstTake latest value, or use cumulative_to_delta
GaugeN/Aavg, min, max, lastRepresents current state, not additive
HistogramDeltasum on countsBucket counts are additive
HistogramCumulativeConvert first, then sumNeed 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.

flowchart LR A[OTLP Input] --> B{Route by Temporality} B -->|cumulative| C[Cumulative to Delta] B -->|delta/gauge| D[Aggregate Metrics] C --> D D --> E[Output]

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 last or convert to delta first
  • Survives scrape gaps
  • Common sources: Prometheus, OpenMetrics

Edge Delta behavior:

  • Automatically separates by temporality
  • Preserves is_monotonic flag
  • Use cumulative_to_delta processor for conversion
  • First point dropped during conversion (no previous value to diff)

See also