🗓️ 06112025 0000

TIME SERIES BASICS

Core Concept: Time series are sequences of (timestamp, value) pairs identified by metric name + labels, collected at regular scrape intervals.

Why It Matters​

Understanding the raw data structure is essential for reasoning about what range functions actually calculate and why visualizations look the way they do.

What Is a Time Series​

A time series is a sequence of samples (data points) for a single metric with a unique label set:

http_requests_total{method="GET", status="200"}
(1699000000, 100) ← timestamp, value
(1699000015, 115)
(1699000030, 132)
(1699000045, 150)

Series identifier = metric name + labels:

  • Metric name: http_requests_total
  • Labels: {method="GET", status="200"}

Each unique label combination creates a separate time series.

How Prometheus Collects Data​

Scrape Intervals​

Prometheus pulls metrics from your application at regular intervals (default 15s):

App exposes: Prometheus scrapes: TSDB stores:
/metrics every 15s (timestamp, value)
↓ ↓ ↓
counter=100 → scrape at t=0 → (t0, 100)
counter=115 → scrape at t=15 → (t15, 115)
counter=132 → scrape at t=30 → (t30, 132)

Key insight: Between scrapes, Prometheus has no data. It only knows values at scrape times.

Instant vs Range Selectors​

Instant Vector Selector​

Returns the most recent sample for each matching time series:

http_requests_total{status="200"}

Returns: (latest_timestamp, latest_value) for each series

Lookback delta (default 5m): If no sample exists within 5 minutes of query time, series is considered stale.

Range Vector Selector​

Returns all samples within a time window:

http_requests_total{status="200"}[5m]

Returns array of samples from last 5 minutes:

[
(t-300s, 100),
(t-285s, 115),
(t-270s, 132),
...
(t, 200)
]

This is what range functions operate on - they receive this array and calculate a single output value.

Label Matching​

Filter time series using label matchers:

MatcherSyntaxExample
Equalitylabel="value"status="200"
Inequalitylabel!="value"status!="500"
Regex matchlabel=~"regex"method=~"GET|POST"
Regex negativelabel!~"regex"path!~"/health.*"

Multiple matchers (AND logic):

http_requests_total{status="200", method="GET", path!~"/health.*"}

Staleness Handling​

Prometheus marks series as stale when:

  • Series disappears between scrapes
  • Target scrape fails
  • Target disappears completely

Stale series are excluded from instant vector queries after lookback delta expires.

When to Use​

  • Instant selectors → current state, alerts, single value displays
  • Range selectors → rate calculations, aggregations over time, trends

Trade-offs​

Scrape interval:

  • Shorter (5s) = more data points, higher resolution, more storage
  • Longer (60s) = fewer points, less resolution, less storage

Lookback delta:

  • Longer = more tolerant of missed scrapes, slower staleness detection
  • Shorter = faster staleness detection, less tolerant of gaps

Quick Reference​

# Instant vector - latest value
metric_name{label="value"}

# Range vector - last 5 minutes of samples
metric_name{label="value"}[5m]

# Label matchers
{status="200"} # exact match
{status!="500"} # not equal
{method=~"GET|POST"} # regex match
{path!~"/health.*"} # regex negative match

# Time units
s - seconds
m - minutes
h - hours
d - days
w - weeks
y - years

References​