Skip to content

Commit 351155c

Browse files
ericallam0ski
authored andcommitted
chore(docs): debounce options
1 parent ba9b0e1 commit 351155c

File tree

1 file changed

+91
-0
lines changed

1 file changed

+91
-0
lines changed

docs/triggering.mdx

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,97 @@ export const myTask = task({
831831

832832
For more information, see our [Idempotency](/idempotency) documentation.
833833

834+
### `debounce`
835+
836+
You can debounce task triggers to consolidate multiple trigger calls into a single delayed run. When a run with the same debounce key already exists in the delayed state, subsequent triggers "push" the existing run's execution time later rather than creating new runs.
837+
838+
This is useful for scenarios like:
839+
840+
- Real-time document indexing where you want to wait for the user to finish typing
841+
- Aggregating webhook events from the same source
842+
- Rate limiting expensive operations while still processing the final request
843+
844+
```ts
845+
// First trigger creates a new run, delayed by 5 seconds
846+
await myTask.trigger({ some: "data" }, { debounce: { key: "user-123", delay: "5s" } });
847+
848+
// If triggered again within 5 seconds, the existing run is pushed later
849+
await myTask.trigger({ updated: "data" }, { debounce: { key: "user-123", delay: "5s" } });
850+
851+
// The run only executes after 5 seconds of no new triggers
852+
// Note: The first payload is used (first trigger wins)
853+
```
854+
855+
<Note>
856+
Debounce keys are scoped to the task identifier, so different tasks can use the same key without
857+
conflicts.
858+
</Note>
859+
860+
The `debounce` option accepts:
861+
862+
- `key` - A unique string to identify the debounce group (scoped to the task)
863+
- `delay` - Duration string specifying how long to delay (e.g., "5s", "1m", "30s")
864+
- `mode` - Optional. Controls which trigger's data is used: `"leading"` (default) or `"trailing"`
865+
866+
**How it works:**
867+
868+
1. First trigger with a debounce key creates a new delayed run
869+
2. Subsequent triggers with the same key (while the run is still delayed) push the execution time further
870+
3. Once no new triggers occur within the delay duration, the run executes
871+
4. After the run starts executing, a new trigger with the same key will create a new run
872+
873+
**Leading vs Trailing mode:**
874+
875+
By default, debounce uses **leading mode** - the run executes with data from the **first** trigger.
876+
877+
With **trailing mode**, each subsequent trigger updates the run's data (payload, metadata, tags, maxAttempts, maxDuration, and machine), so the run executes with data from the **last** trigger:
878+
879+
```ts
880+
// Leading mode (default): runs with first payload
881+
await myTask.trigger({ count: 1 }, { debounce: { key: "user-123", delay: "5s" } });
882+
await myTask.trigger({ count: 2 }, { debounce: { key: "user-123", delay: "5s" } });
883+
// After 5 seconds, runs with { count: 1 }
884+
885+
// Trailing mode: runs with last payload
886+
await myTask.trigger(
887+
{ count: 1 },
888+
{ debounce: { key: "user-123", delay: "5s", mode: "trailing" } }
889+
);
890+
await myTask.trigger(
891+
{ count: 2 },
892+
{ debounce: { key: "user-123", delay: "5s", mode: "trailing" } }
893+
);
894+
// After 5 seconds, runs with { count: 2 }
895+
```
896+
897+
Use **trailing mode** when you want to process the most recent data, such as:
898+
899+
- Saving the latest version of a document after edits stop
900+
- Processing the final state after a series of rapid updates
901+
902+
**With `triggerAndWait`:**
903+
904+
When using `triggerAndWait` with debounce, the parent run blocks on the existing debounced run if one exists:
905+
906+
```ts
907+
export const parentTask = task({
908+
id: "parent-task",
909+
run: async (payload: string) => {
910+
// Both will wait for the same run
911+
const result = await childTask.triggerAndWait(
912+
{ data: payload },
913+
{ debounce: { key: "shared-key", delay: "3s" } }
914+
);
915+
return result;
916+
},
917+
});
918+
```
919+
920+
<Note>
921+
Idempotency keys take precedence over debounce keys. If both are provided and an idempotency match
922+
is found, it wins.
923+
</Note>
924+
834925
### `queue`
835926

836927
When you trigger a task you can override the concurrency limit. This is really useful if you sometimes have high priority runs.

0 commit comments

Comments
 (0)