# `Otel.Metrics.Aggregation.ExplicitBucketHistogram`
[🔗](https://github.com/yangbancode/otel/blob/main/lib/otel/metrics/aggregation/explicit_bucket_histogram.ex#L1)

Explicit bucket histogram aggregation.

Uses `:counters` for thread-safe bucket increments and
`ets:update_counter` / `ets:update_element` for atomic
count, sum, min, and max updates.

ETS entry format:
`{key, counters_ref, min, max, sum, count, start_time, reservoir_state}`.

The eighth slot holds the exemplar reservoir state
(`Otel.Metrics.Exemplar.Reservoir.AlignedHistogramBucket`) so a
single ETS row carries everything `collect/3` needs to emit a
datapoint with exemplars.

Cumulative-only — `collect/3` returns running totals since
stream start. Delta temporality is not supported (minikube
hardcodes cumulative; spec `metrics/sdk.md` L1290-L1297 default).

## Configuration parameters

`Otel.Metrics.Meter.register_instrument/3` resolves
`:boundaries` from the instrument's advisory
`:explicit_bucket_boundaries` (when present).

| Key | Default | Description |
|---|---|---|
| `:boundaries` | `@default_boundaries` (15 OTel-default buckets) | Bucket boundaries per `metrics/sdk.md` L660-L661 |

Spec `metrics/sdk.md` L662 also lists a `RecordMinMax` Stream
config knob; minikube has no Views so it is permanently on
and not exposed here. The encoder's `min: nil` / `max: nil`
path still exists for the brief concurrent-collect window
before the first measurement updates the ETS row.

# `aggregate`

```elixir
@spec aggregate(
  metrics_tab :: :ets.table(),
  key :: term(),
  value :: number(),
  opts :: map()
) :: :ok
```

# `collect`

```elixir
@spec collect(
  metrics_tab :: :ets.table(),
  stream_key :: String.t(),
  opts :: map()
) :: [Otel.Metrics.Aggregation.datapoint()]
```

# `default_boundaries`

```elixir
@spec default_boundaries() :: [number()]
```

# `offer_exemplar`

```elixir
@spec offer_exemplar(
  metrics_tab :: :ets.table(),
  key :: term(),
  value :: number(),
  time :: non_neg_integer(),
  filtered_attrs :: %{required(String.t()) =&gt; term()},
  ctx :: Otel.Ctx.t()
) :: :ok
```

---

*Consult [api-reference.md](api-reference.md) for complete listing*
