> ## Documentation Index
> Fetch the complete documentation index at: https://docs.automate.ax/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Automate.ax automations are TypeScript programs.
> Use Bun for installation and command examples.
> Use Automate.ax for the product name and automate.ax for the package, CLI, and domain.
> Treat documented public APIs as current; do not invent transitional or deprecated names.

# Control bursts

> Debounce, buffer, and limit the timing of repeated signal occurrences.

Burst operators coordinate repeated occurrences across contexts. Their source must use `.keyBy()` for independent partitions or `.globally()` for one shared partition. Locally closed inputs contribute no occurrence.

## `funnel()`

`funnel(signal, options)` applies one durable timing and output policy to each source partition.

```ts theme={null}
import { funnel } from "automate.ax"

const firstMessagePerMinute = funnel(message.globally(), {
  minGap: "1m",
  triggerAt: "start",
})
```

| Option                         | Meaning                                                                                                                  |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------ |
| `minQuietPeriod`               | Wait this long after the latest admitted occurrence before an end emission.                                              |
| `maxBurstDuration`             | Cap a burst's lifetime from its first occurrence.                                                                        |
| `minGap`                       | Require this interval between emitted results.                                                                           |
| `triggerAt`                    | Emit at `"start"`, `"end"`, or `"both"`; defaults to `"end"`.                                                            |
| `select`                       | For an end emission, choose `"first"` or `"latest"`; defaults to `"latest"`.                                             |
| `buffer`                       | Emit every trailing occurrence in arrival order instead of selecting one.                                                |
| `inheritConflictingValuesFrom` | For buffered output, choose `"first"` or `"last"` parent for otherwise ambiguous inherited values; defaults to `"last"`. |

Timing options accept type-checked compact strings, millisecond numbers, or compatible signals.

End-triggered funnels require `minQuietPeriod` or `maxBurstDuration`. Start and both-edge funnels may instead use `minGap`. Start-only funnels emit the first occurrence immediately and ignore the remainder of that burst, so they do not accept `select` or `buffer`. End and both-edge funnels may select one trailing occurrence or buffer all trailing occurrences.

A selecting funnel preserves the source's keyed or global partition. A buffered funnel returns an ordinary `Signal<T[]>`.

## `debounce()`

`debounce(signal, duration)` emits the latest occurrence after that partition remains quiet for the duration. It is the selecting funnel preset `{ minQuietPeriod: duration }` and preserves the source's keyed or global partition.

```ts theme={null}
import { debounce } from "automate.ax"

const settledMessage = debounce(
  message.keyBy((value) => value.customerId),
  "5m",
)
```

Key before debouncing when independent entities need independent quiet periods. Use `.globally()` only when every occurrence should reset the same timer.

## `window()`

`window(signal, duration, options?)` opens a fixed-duration window with the first occurrence and emits every admitted occurrence before its deadline. It always includes the opening occurrence.

```ts theme={null}
import { window } from "automate.ax"

const recentMessages = window(message.globally(), "5m")
```

`window` is the buffered funnel preset `{ buffer: true, maxBurstDuration: duration }` and returns an ordinary `Signal<T[]>`. The last parent supplies otherwise ambiguous inherited values by default; pass `{ inheritConflictingValuesFrom: "first" }` to choose the first.

See [`collect`](/reference/signals/coordinate-occurrences#collect) for count-bounded batches and [`delay`](/reference/signals/select-and-time#delay) for timing one continuation.
