Metrics schema — System Protocol reference Metrics Protocol - Performance and Operational Metrics. Reference for HistogramBucketConfig and 13 more: every property with its type and default.
Metrics Protocol - Performance and Operational Metrics
Comprehensive metrics collection and monitoring:
Counter, Gauge, Histogram, Summary metric types
Time-series data collection
SLI/SLO definitions
Metric aggregation and export
Integration with monitoring systems (Prometheus, etc.)
Source: packages/spec/src/system/metrics.zod.ts
import { HistogramBucketConfigSchema, MetricAggregationConfigSchema, MetricAggregationType, MetricDataPointSchema, MetricDefinitionSchema, MetricExportConfigSchema, MetricLabelsSchema, MetricType, MetricUnit, MetricsConfigSchema, ServiceLevelIndicatorSchema, ServiceLevelObjectiveSchema, TimeSeriesSchema, TimeSeriesDataPointSchema } from '@objectstack/spec/system' ;
import type { HistogramBucketConfig, MetricAggregationConfig, MetricAggregationType, MetricDataPoint, MetricDefinition, MetricExportConfig, MetricLabels, MetricType, MetricUnit, MetricsConfig, ServiceLevelIndicator, ServiceLevelObjective, TimeSeries, TimeSeriesDataPoint } from '@objectstack/spec/system' ;
// Validate data
const result = HistogramBucketConfigSchema. parse (data);
Histogram bucket configuration
Property Type Required Description type Enum<'linear' | 'exponential' | 'explicit'>✅ Bucket type linear { start: number; width: number; count: integer }optional exponential { start: number; factor: number; count: integer }optional explicit { boundaries: number[] }optional
Property Type Required Description start number✅ Start value width number✅ Bucket width count integer✅ Number of buckets
Property Type Required Description start number✅ Start value factor number✅ Growth factor count integer✅ Number of buckets
Property Type Required Description boundaries number[]✅ Bucket boundaries
Metric aggregation configuration
Property Type Required Description type Enum<'sum' | 'avg' | 'min' | 'max' | 'count' | 'p50' | 'p75' | 'p90' | 'p95' | 'p99' | 'p999' | 'rate' | 'stddev'>✅ Aggregation type window { durationSeconds: integer; sliding?: boolean; slideInterval?: integer }optional groupBy string[]optional Group by label names filters Record<string, any>optional Filter criteria
Property Type Required Description durationSeconds integer✅ Window duration in seconds size neveroptional [REMOVED] The aggregation/SLI window key size was renamed to durationSeconds in @objectstack/spec 17 — the unit of a duration-shaped number lives in the key name, not only in the describe prose. The new name is not sizeSeconds: size means a byte or row count everywhere else in this spec, so the rename drops it rather than bolting a unit onto it. Rename window.size to window.durationSeconds on both MetricAggregationConfig and ServiceLevelIndicator; the value (seconds) is unchanged. sliding booleanoptional (default: false) slideInterval integeroptional Slide interval for sliding windows, in seconds
Metric aggregation type
sum
avg
min
max
count
p50
p75
p90
p95
p99
p999
rate
stddev
Metric data point
Property Type Required Description name string✅ Metric name type Enum<'counter' | 'gauge' | 'histogram' | 'summary'>✅ Metric type timestamp string✅ Observation timestamp value numberoptional Metric value labels Record<string, string>optional Metric labels histogram { count: integer; sum: number; buckets: object[] }optional summary { count: integer; sum: number; quantiles: object[] }optional
Property Type Required Description count integer✅ Total count sum number✅ Sum of all values buckets { upperBound: number; count: integer }[]✅ Histogram buckets
Property Type Required Description count integer✅ Total count sum number✅ Sum of all values quantiles { quantile: number; value: number }[]✅ Summary quantiles
Metric definition
Property Type Required Description name string✅ Metric name (snake_case) label stringoptional Display label type Enum<'counter' | 'gauge' | 'histogram' | 'summary'>✅ Metric type unit Enum<'nanoseconds' | 'microseconds' | 'milliseconds' | 'seconds' | 'minutes' | 'hours' | 'days' | 'bytes' | 'kilobytes' | 'megabytes' | 'gigabytes' | 'terabytes' | … +8 more>optional Metric unit description stringoptional Metric description labelNames string[]optional (default: []) Label names histogram { type: Enum<'linear' | 'exponential' | 'explicit'>; linear?: object; exponential?: object; explicit?: object }optional Histogram bucket configuration summary { quantiles?: number[]; maxAgeSeconds?: integer; ageBuckets?: integer }optional enabled booleanoptional (default: true)
nanoseconds
microseconds
milliseconds
seconds
minutes
hours
days
bytes
kilobytes
megabytes
gigabytes
terabytes
requests_per_second
events_per_second
bytes_per_second
percent
ratio
count
operations
custom
Property Type Required Description type Enum<'linear' | 'exponential' | 'explicit'>✅ Bucket type linear { start: number; width: number; count: integer }optional exponential { start: number; factor: number; count: integer }optional explicit { boundaries: number[] }optional
Property Type Required Description quantiles number[]optional (default: [0.5,0.9,0.99]) maxAgeSeconds integeroptional (default: 600) Max age of observations in seconds maxAge neveroptional [REMOVED] MetricDefinition.summary.maxAge was renamed to maxAgeSeconds in @objectstack/spec 17 — the unit of a duration-shaped number lives in the key name, not only in the describe prose. Its unit (seconds) lived in a source JSDoc only and the published description named none, so a reader of the reference page could not tell 600 seconds from 600 milliseconds. The new name keeps the age stem instead of becoming durationSeconds, because the sibling key ageBuckets counts buckets of that same age. Rename the key to maxAgeSeconds; the value (seconds) is unchanged. ageBuckets integeroptional (default: 5)
Metric export configuration
Property Type Required Description type Enum<'prometheus' | 'openmetrics' | 'graphite' | 'statsd' | 'influxdb' | 'datadog' | 'cloudwatch' | 'stackdriver' | 'azure_monitor' | 'http' | 'custom'>✅ Export type endpoint stringoptional Export endpoint intervalSeconds integeroptional (default: 60) Export interval in seconds interval neveroptional [REMOVED] MetricExportConfig.interval was renamed to intervalSeconds in @objectstack/spec 17 — the unit of a duration-shaped number lives in the key name, not only in the describe prose. Its unit (seconds) lived in a source JSDoc only and the key carried no describe at all, so a reader of the reference page could not tell 60 seconds from 60 milliseconds. Rename the key to intervalSeconds; the value (seconds) is unchanged. batch { enabled?: boolean; size?: integer }optional auth { type: Enum<'none' | 'basic' | 'bearer' | 'api_key'>; username?: string; password?: string; token?: string; … }optional config Record<string, any>optional Additional configuration
Property Type Required Description type Enum<'none' | 'basic' | 'bearer' | 'api_key'>✅ Auth type username stringoptional password stringoptional token stringoptional apiKey stringoptional
Metric labels
Type: Record<string, string>
Metric type
counter
gauge
histogram
summary
Metric unit
nanoseconds
microseconds
milliseconds
seconds
minutes
hours
days
bytes
kilobytes
megabytes
gigabytes
terabytes
requests_per_second
events_per_second
bytes_per_second
percent
ratio
count
operations
custom
Metrics configuration
Property Type Required Description name string✅ Configuration name (snake_case, max 64 chars) label string✅ Display label enabled booleanoptional (default: true) metrics { name: string; label?: string; type: Enum<'counter' | 'gauge' | 'histogram' | 'summary'>; unit?: Enum<'nanoseconds' | 'microseconds' | 'milliseconds' | 'seconds' | 'minutes' | …>; … }[]optional (default: []) defaultLabels Record<string, string>optional (default: {}) Metric labels aggregations { type: Enum<'sum' | 'avg' | 'min' | 'max' | 'count' | 'p50' | 'p75' | 'p90' | 'p95' | 'p99' | …>; window?: object; groupBy?: string[]; filters?: Record<string, any> }[]optional (default: []) slis { name: string; label: string; description?: string; metric: string; … }[]optional (default: []) slos { name: string; label: string; description?: string; sli: string; … }[]optional (default: []) exports { type: Enum<'prometheus' | 'openmetrics' | 'graphite' | 'statsd' | 'influxdb' | 'datadog' | …>; endpoint?: string; intervalSeconds?: integer; batch?: object; … }[]optional (default: []) collectionIntervalSeconds integeroptional (default: 15) Collection interval in seconds collectionInterval neveroptional [REMOVED] MetricsConfig.collectionInterval was renamed to collectionIntervalSeconds in @objectstack/spec 17 — the unit of a duration-shaped number lives in the key name, not only in the describe prose. Its unit (seconds) lived in a source JSDoc only and the key carried no describe at all, so a reader of the reference page could not tell 15 seconds from 15 milliseconds. The qualifier is kept — collectionIntervalSeconds, not intervalSeconds — because MetricExportConfig.intervalSeconds is a different cadence one def over. Rename the key to collectionIntervalSeconds; the value (seconds) is unchanged. retention { durationSeconds?: integer; downsampling?: object[] }optional cardinalityLimits { maxLabelCombinations?: integer; onLimitExceeded?: Enum<'drop' | 'sample' | 'alert'> }optional
Metric definition
Property Type Required Description name string✅ Metric name (snake_case) label stringoptional Display label type Enum<'counter' | 'gauge' | 'histogram' | 'summary'>✅ Metric type unit Enum<'nanoseconds' | 'microseconds' | 'milliseconds' | 'seconds' | 'minutes' | …>optional Metric unit description stringoptional Metric description labelNames string[]optional (default: []) Label names histogram { type: Enum<'linear' | 'exponential' | 'explicit'>; linear?: object; exponential?: object; explicit?: object }optional Histogram bucket configuration summary { quantiles?: number[]; maxAgeSeconds?: integer; ageBuckets?: integer }optional enabled booleanoptional (default: true)
Metric aggregation configuration
Property Type Required Description type Enum<'sum' | 'avg' | 'min' | 'max' | 'count' | 'p50' | 'p75' | 'p90' | 'p95' | 'p99' | …>✅ Aggregation type window { durationSeconds: integer; sliding?: boolean; slideInterval?: integer }optional groupBy string[]optional Group by label names filters Record<string, any>optional Filter criteria
Service Level Indicator
Property Type Required Description name string✅ SLI name (snake_case) label string✅ Display label description stringoptional SLI description metric string✅ Base metric name type Enum<'availability' | 'latency' | 'throughput' | 'error_rate' | 'saturation' | 'custom'>✅ SLI type successCriteria { threshold: number; operator: Enum<'lt' | 'lte' | 'gt' | 'gte' | 'eq'>; percentile?: number }✅ Success criteria — a structured threshold rule. A CEL predicate is NOT accepted here: that arm was removed in 17.5.0 because nothing evaluated it. window { durationSeconds: integer; rolling?: boolean }✅ Measurement window enabled booleanoptional (default: true)
Service Level Objective
Property Type Required Description name string✅ SLO name (snake_case) label string✅ Display label description stringoptional SLO description sli string✅ SLI name target number✅ Target percentage period { type: Enum<'rolling' | 'calendar'>; durationSeconds?: integer; calendar?: Enum<'daily' | 'weekly' | 'monthly' | 'quarterly' | 'yearly'> }✅ Time period errorBudget { enabled?: boolean; alertThreshold?: number; burnRateWindows?: object[] }optional alerts { name: string; severity: Enum<'info' | 'warning' | 'critical'>; condition: object }[]optional (default: []) enabled booleanoptional (default: true)
Metric export configuration
Property Type Required Description type Enum<'prometheus' | 'openmetrics' | 'graphite' | 'statsd' | 'influxdb' | 'datadog' | …>✅ Export type endpoint stringoptional Export endpoint intervalSeconds integeroptional (default: 60) Export interval in seconds interval neveroptional [REMOVED] MetricExportConfig.interval was renamed to intervalSeconds in @objectstack/spec 17 — the unit of a duration-shaped number lives in the key name, not only in the describe prose. Its unit (seconds) lived in a source JSDoc only and the key carried no describe at all, so a reader of the reference page could not tell 60 seconds from 60 milliseconds. Rename the key to intervalSeconds; the value (seconds) is unchanged. batch { enabled?: boolean; size?: integer }optional auth { type: Enum<'none' | 'basic' | 'bearer' | 'api_key'>; username?: string; password?: string; token?: string; … }optional config Record<string, any>optional Additional configuration
Property Type Required Description durationSeconds integeroptional (default: 604800) Retention duration in seconds period neveroptional [REMOVED] MetricsConfig.retention.period was renamed to durationSeconds in @objectstack/spec 17 — the unit of a duration-shaped number lives in the key name, not only in the describe prose. Its unit (seconds) lived in a source JSDoc only and the key carried no describe at all, so a reader of the reference page could not tell 604800 seconds from 604800 milliseconds. The new name is not periodSeconds: period is calendar vocabulary elsewhere in this spec (ServiceLevelObjective.period.type selects rolling or calendar, PluginRegistryEntry.pricing.billingPeriod is monthly or yearly), so it would have kept the ambiguous half of the name, and durationSeconds is what this file already calls a length of time. Rename the key to durationSeconds; the value (seconds) is unchanged. downsampling { afterSeconds: integer; resolution: integer }[]optional
Service Level Indicator
Property Type Required Description name string✅ SLI name (snake_case) label string✅ Display label description stringoptional SLI description metric string✅ Base metric name type Enum<'availability' | 'latency' | 'throughput' | 'error_rate' | 'saturation' | 'custom'>✅ SLI type successCriteria { threshold: number; operator: Enum<'lt' | 'lte' | 'gt' | 'gte' | 'eq'>; percentile?: number }✅ Success criteria — a structured threshold rule. A CEL predicate is NOT accepted here: that arm was removed in 17.5.0 because nothing evaluated it. window { durationSeconds: integer; rolling?: boolean }✅ Measurement window enabled booleanoptional (default: true)
Property Type Required Description threshold number✅ Threshold value operator Enum<'lt' | 'lte' | 'gt' | 'gte' | 'eq'>✅ Comparison operator percentile numberoptional Percentile (0-1)
Property Type Required Description durationSeconds integer✅ Window duration in seconds size neveroptional [REMOVED] The aggregation/SLI window key size was renamed to durationSeconds in @objectstack/spec 17 — the unit of a duration-shaped number lives in the key name, not only in the describe prose. The new name is not sizeSeconds: size means a byte or row count everywhere else in this spec, so the rename drops it rather than bolting a unit onto it. Rename window.size to window.durationSeconds on both MetricAggregationConfig and ServiceLevelIndicator; the value (seconds) is unchanged. rolling booleanoptional (default: true)
Service Level Objective
Property Type Required Description name string✅ SLO name (snake_case) label string✅ Display label description stringoptional SLO description sli string✅ SLI name target number✅ Target percentage period { type: Enum<'rolling' | 'calendar'>; durationSeconds?: integer; calendar?: Enum<'daily' | 'weekly' | 'monthly' | 'quarterly' | 'yearly'> }✅ Time period errorBudget { enabled?: boolean; alertThreshold?: number; burnRateWindows?: object[] }optional alerts { name: string; severity: Enum<'info' | 'warning' | 'critical'>; condition: object }[]optional (default: []) enabled booleanoptional (default: true)
Property Type Required Description type Enum<'rolling' | 'calendar'>✅ Period type durationSeconds integeroptional Duration in seconds duration neveroptional [REMOVED] ServiceLevelObjective.period.duration was renamed to durationSeconds in @objectstack/spec 17 — the unit of a duration-shaped number lives in the key name, not only in the describe prose. Rename the key to durationSeconds; the value (seconds) is unchanged. calendar Enum<'daily' | 'weekly' | 'monthly' | 'quarterly' | 'yearly'>optional
Property Type Required Description name string✅ Alert name severity Enum<'info' | 'warning' | 'critical'>✅ Alert severity condition { type: Enum<'slo_breach' | 'error_budget' | 'burn_rate'>; threshold?: number }✅ Alert condition
Time series
Property Type Required Description name string✅ Series name labels Record<string, string>optional Series labels dataPoints { timestamp: string; value: number; labels?: Record<string, string> }[]✅ Data points startTime stringoptional Start time endTime stringoptional End time
Time series data point
Property Type Required Description timestamp string✅ Timestamp value number✅ Value labels Record<string, string>optional Labels
Time series data point
Property Type Required Description timestamp string✅ Timestamp value number✅ Value labels Record<string, string>optional Labels