Explore documentation
Unifying metrics schema (Feb ’26)
We’re unifying how we store user-defined metrics extracted from logs and spans alongside Prometheus metrics.
Going forward, there’s just 1 way to query everything as follows:
Schema Overview
The new row-based schema stores all data in a unified format with:
- Metrics stored as named values with labels in a
tagsmap - Original log data accessible via
_row_type = 'log' - Aggregated metric functions for efficient querying
| Old Schema | New Schema |
|---|---|
Direct column (e.g., response_status) |
label('response_status') |
buckets (array of tuples) |
bucket_bounds + bucket_counts (separate arrays) |
p50, p90, p95, p99 (direct columns) |
quantilePrometheusHistogramArrayMerge(0.XX)(bucket_quantiles) |
_row_type = 'logs' |
_row_type = 'log' (singular) |
Accessing Labels/Tags
All custom/dynamic columns that were previously accessed directly must now use the label() function. Labels are always strings, so toString(label(...)) is redundant.
Standard Columns (No Changes Needed)
The following columns are part of the schema itself and do NOT need the label() wrapper: time, dt, name, _row_type, series_id, tags, events_count, value_avg, value_min, value_max, rate_avg, bucket_bounds, bucket_counts, bucket_quantiles, bucket_sum, bucket_count, bucket_min, bucket_max.
Row Type Filtering
Each ingested event creates multiple rows: 1 row for the original event (_row_type = 'log' or 'span') and multiple for extracted metrics (_row_type = 'extracted_metric').
| Value | Alias | Description |
|---|---|---|
1 |
'log' |
Original log event |
2 |
'extracted_metric' |
Metrics extracted from logs/spans |
3 |
'span' |
Original span event |
Count log events:
Do NOT use _row_type = 'log' or 'span' when querying named metrics:
Type Handling for Labels
Since labels are always strings, you must handle type conversions explicitly when comparing to numbers.
Numeric Comparison (Required for ranges/inequalities):
Histogram/Bucket Data
The new schema uses bucket_bounds and bucket_counts (deltas). sumForEachMerge() is used to sum these deltas.
Quantiles (Percentiles):
Use the histogramQuantile(p) helper function for single metrics, or quantilePrometheusHistogramArrayMergeIf(p)(bucket_quantiles, condition) for multiple metrics.
Event Counting
For aggregated metrics queries, use countMerge(events_count).
This change will go in effect for existing organizations during February ’26. Let us know at hello@betterstack.com if you have any feedback. We hope this change will make the product more straightforward and intuitive going forward.