# 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`