# monitor.rollup Turns a raw metric series into one row per fixed time bucket (a minute, an hour, a day) with the count, min, max, average, sum and last value: the table behind a latency or throughput chart, or a coarser copy kept for longer retention. `charts.downsample` is the other tool: it picks points that keep a line's shape (LTTB); this one aggregates. ## Buckets Buckets start at `from` and step by `bucketSeconds`, so they are aligned to `from`, not to the epoch: pass a `from` on a minute or hour boundary to get round buckets. Each is half-open, `start <= at < end`, like `monitor.series-window`, so no sample lands in two buckets. The last bucket is clipped at `to` when the window is not a whole number of buckets. Empty buckets are returned too (count 0, sum 0, the rest null). A chart then shows a gap where data is missing instead of drawing a line straight across it, and every result for the same window has the same number of rows. `from == to` gives no buckets. More than 10000 buckets is refused: that is almost always a bucket size in the wrong unit (seconds for minutes). ## Average `avg` is `sum / count` rounded half up with `math.round-div`, whose half-up rounds halves away from zero: -1 and -2 average to -2, as 1 and 2 average to 2 (`Math.round(-1.5)` in JavaScript gives -1). Keep the `sum` and `count` if you need to combine buckets later: averaging averages is wrong when counts differ. ## Errors - `bucketSeconds must be at least 1, received 0` - `bucketSeconds must be a whole number of seconds` - `too many buckets: 10001, at most 10000` - from `monitor.series-window`: `from must not be after to: 200 > 100`, `samples must be in strictly ascending time order: 5 follows 10`, `from and to must be whole seconds`