Embedded time series storage for Elixir.
TimelessMetrics runs as an embedded store inside your application and defaults to a Rust-backed engine for raw point ingestion and queries. Administrative data such as annotations, alerts, scrape targets, and rollup metadata stays on the Elixir side.
Quick Start
# Add to your supervision tree
children = [
{TimelessMetrics, name: :metrics, data_dir: "/tmp/metrics"}
]
# Write metrics
TimelessMetrics.write(:metrics, "cpu_usage", %{"host" => "web-1"}, 73.2)
# Query
TimelessMetrics.query(:metrics, "cpu_usage", %{"host" => "web-1"},
from: System.os_time(:second) - 3600,
to: System.os_time(:second)
)
Summary
Functions
Acknowledge an alert history entry by ID.
List recent alert history entries.
Create an annotation (event marker).
Query annotations within a time range.
Create a consistent online backup.
Start a TimelessMetrics instance as part of a supervision tree.
Clear alert history entries.
Create an alert rule.
Delete an alert rule.
Delete an annotation by ID.
Detect anomalies in matching series.
Force retention enforcement now.
Evaluate all alert rules against current data.
Force flush all buffered data to disk.
Forecast future values for matching series.
Get metadata for a metric.
Get store info and statistics.
List distinct values for a specific label key across all series of a metric.
Get the latest value for a series.
Get the latest value for ALL series matching a metric name and label filter.
Get the latest text value for a series.
List all alert rules with current state.
List all distinct metric names in the store.
List all series for a given metric name.
No-op for sharded engine (no per-series blocks to merge).
Query raw time series points for a single series (exact label match).
Query with time-bucket aggregation for a single series (exact label match).
Query with cross-series aggregation, grouping results by a label key.
Query with cross-series aggregation across multiple metrics, with group-by.
Query with aggregation across multiple series matching a label filter.
Query with aggregation and threshold filtering.
Query with aggregation across multiple metric names matching a label filter.
Query pre-computed daily rollup data.
Query raw points across multiple series matching a label filter.
Query text time series points for a single series.
Query text points across multiple series matching a label filter.
Register metadata for a metric (type, unit, description).
Resolve a series to an integer ID for use with write_resolved/4.
Force a daily rollup run.
Sort results by a value function and take top N.
Update an alert rule (partial update). Returns :ok.
Write a single metric point.
Write a batch of metric points.
Write entries directly, one per unique series. Same as write_batch/2 for the sharded engine.
Write directly using a pre-resolved series ID. Zero lookup cost.
Write a single text metric point.
Write a batch of text metric points.
Functions
Acknowledge an alert history entry by ID.
List recent alert history entries.
Options: :limit, :rule_id, :acknowledged (true/false/nil).
Create an annotation (event marker).
Returns {:ok, id}.
Query annotations within a time range.
Returns {:ok, [%{id: n, timestamp: ts, title: "...", description: "...", tags: [...]}]}.
Create a consistent online backup.
Start a TimelessMetrics instance as part of a supervision tree.
Clear alert history entries.
Options: :acknowledged_only (default true), :before (timestamp cutoff).
Create an alert rule.
Returns {:ok, rule_id}.
Delete an alert rule.
Delete an annotation by ID.
Detect anomalies in matching series.
Returns {:ok, [%{labels: map, analysis: [%{timestamp, value, expected, score, anomaly}]}, ...]}.
Force retention enforcement now.
Evaluate all alert rules against current data.
Force flush all buffered data to disk.
Forecast future values for matching series.
Returns {:ok, [%{labels: map, data: [{ts, val}], forecast: [{ts, val}]}, ...]}.
Get metadata for a metric.
Returns {:ok, %{type: :gauge, unit: "%", description: "..."}} or {:ok, nil}.
Get store info and statistics.
List distinct values for a specific label key across all series of a metric.
Returns {:ok, ["web-1", "web-2", ...]}.
Get the latest value for a series.
Returns {:ok, {timestamp, value}} or {:ok, nil}.
Get the latest value for ALL series matching a metric name and label filter.
Returns {:ok, [%{labels: %{...}, timestamp: ts, value: val}, ...]}.
Get the latest text value for a series.
List all alert rules with current state.
List all distinct metric names in the store.
Returns {:ok, ["cpu_usage", "mem_usage", ...]}.
List all series for a given metric name.
Returns {:ok, [%{labels: %{"host" => "web-1"}, ...}, ...]}.
No-op for sharded engine (no per-series blocks to merge).
Query raw time series points for a single series (exact label match).
Options
:from- Start timestamp (unix seconds, default: 0):to- End timestamp (unix seconds, default: now)
Returns {:ok, [{timestamp, value}, ...]}.
Query with time-bucket aggregation for a single series (exact label match).
Options
:from- Start timestamp:to- End timestamp:bucket- Bucket size::minute,:hour,:day, or{n, :seconds}:aggregate- Aggregate function::avg,:min,:max,:sum,:count,:last,:first
Returns {:ok, [{bucket_timestamp, aggregate_value}, ...]}.
Query with cross-series aggregation, grouping results by a label key.
Returns {:ok, [%{group: %{"hostname" => "host_0"}, data: [{ts, val}]}, ...]}.
Query with cross-series aggregation across multiple metrics, with group-by.
Returns {:ok, [%{group: %{...}, data: [{ts, val}]}, ...]}.
Query with aggregation across multiple series matching a label filter.
Returns {:ok, [%{labels: %{...}, data: [{bucket_ts, agg_value}, ...]}, ...]}.
Query with aggregation and threshold filtering.
Returns {:ok, [%{labels: %{...}, data: [{ts, val}]}, ...]}.
Query with aggregation across multiple metric names matching a label filter.
Returns {:ok, [%{metric: name, labels: %{...}, data: [{ts, val}, ...]}, ...]}.
Query pre-computed daily rollup data.
Returns {:ok, [%{bucket: ts, avg: v, min: v, max: v, count: n, sum: v, last: v}, ...]}.
Query raw points across multiple series matching a label filter.
Returns {:ok, [%{labels: %{...}, points: [{ts, val}, ...]}, ...]}.
Query text time series points for a single series.
Query text points across multiple series matching a label filter.
Register metadata for a metric (type, unit, description).
Resolve a series to an integer ID for use with write_resolved/4.
Cache the result for repeated writes to the same series.
Force a daily rollup run.
Sort results by a value function and take top N.
Update an alert rule (partial update). Returns :ok.
Write a single metric point.
Parameters
store- The store name (atom)metric_name- String metric name (e.g., "cpu_usage")labels- Map of string labels (e.g., %{"host" => "web-1"})value- Numeric value (float or integer)opts- Optional keyword list::timestamp- Unix timestamp in seconds (default: now)
Write a batch of metric points.
Each entry is a tuple of {metric_name, labels, value} or
{metric_name, labels, value, timestamp}.
Write entries directly, one per unique series. Same as write_batch/2 for the sharded engine.
Write directly using a pre-resolved series ID. Zero lookup cost.
sid = TimelessMetrics.resolve_series(:metrics, "cpu_usage", %{"host" => "web-1"})
TimelessMetrics.write_resolved(:metrics, sid, 73.2, timestamp: ts)
Write a single text metric point.
Write a batch of text metric points.