Debounce jobs accumulate incoming events and flush them in a single batch execution. The flush is triggered either after a configurable delay from the first event or when the event count reaches a maximum.
Debounce.make(config)
Creates an unregistered debounce job definition. The job name is assigned later via the key you use in createDurableJobs.
DebounceMakeConfig fields
Effect Schema for validating incoming events. Every event passed to
.add() is decoded against this schema before being stored.How long to wait after the first event before flushing. Accepts any
Duration.DurationInput — a string such as "5 seconds", a Duration value, or milliseconds as a number. The timer resets if maxEvents has not been reached.The function called when the debounce flushes. Must return
Effect<void, E, never>. Use .pipe(Effect.provide(layer)) to satisfy any service requirements.Schema for the persisted state. When omitted the state schema defaults to
eventSchema, and each new event replaces the previous state with itself. Provide an explicit stateSchema when you want onEvent to accumulate events into a different shape.Maximum number of events to accumulate before flushing immediately, regardless of the
flushAfter timer. Omit to rely solely on the timer.A reducer called for every incoming event. It receives the current state and the new event, and must return the updated state as
Effect<S, never, never>. When omitted, the default behaviour is to replace the state with the latest event (equivalent to Effect.succeed(ctx.event as S)).Automatic retry configuration for
execute failures.Controls the log level for this job’s internal logs.
| Value | Behavior |
|---|---|
false (default) | LogLevel.Error — only failures |
true | LogLevel.Debug — all logs |
LogLevel.Warning | Warnings and above |
LogLevel.None | Silent |
DebounceExecuteContext<S>
The context passed to execute when the debounce flushes.
| Property | Type | Description |
|---|---|---|
state | Effect<S> | Accumulated state at flush time |
eventCount | Effect<number> | Total events received since the debounce started |
flushReason | "maxEvents" | "flushAfter" | "manual" | What triggered this flush |
debounceStartedAt | Effect<number> | Timestamp (ms) when the first event arrived |
executionStartedAt | number | Timestamp (ms) when this execution started |
attempt | number | Current retry attempt (1 = first try) |
isRetry | boolean | true when this is a retry of a previous failure |
Lazily loads the accumulated state from Durable Object storage. Yield it to get the value:
The total number of events accumulated in this debounce window. Yield it to get the count:
Why this flush was triggered:
| Value | Description |
|---|---|
"flushAfter" | The flushAfter timer expired |
"maxEvents" | The maxEvents threshold was reached |
"manual" | The client called .flush() directly |
Unix timestamp in milliseconds of when the first event in this window arrived.
Unix timestamp in milliseconds of when this specific execution started. Available synchronously (no yield needed).
Retry attempt number within this flush.
1 on the first attempt, 2+ on retries.true when attempt > 1.DebounceEventContext<I, S>
The context passed to onEvent for each incoming event.
| Property | Type | Description |
|---|---|---|
event | I | The incoming event (already validated against eventSchema) |
state | S | Current accumulated state (synchronous value, not an Effect) |
eventCount | number | Number of events accumulated so far (synchronous) |
instanceId | string | Durable Object instance ID |
On the very first event,
state is initialized to event (cast to S). If your stateSchema differs from eventSchema, ensure the first event is always a valid S or handle the first-event case in onEvent.The incoming event, already decoded against
eventSchema.The current accumulated state. On the first event this equals
event cast to S. This is a direct value — no yield needed.The total number of events accumulated before this one.
0 on the first event. Synchronous — no yield needed.The Durable Object instance ID in the format
debounce:{jobName}:{userProvidedId}.