Skip to content

Deduplication

Typed Tasks includes a flexible deduplication system with both manual and automatic options.

How It Works

1. Manual Deduplication via taskName

When you provide a taskName in the scheduler options, Cloud Tasks uses this name as the task identifier. If a task with the exact same name already exists in the queue (or has existed recently), the new task creation fails with an ALREADY_EXISTS error — which typed-tasks handles gracefully by logging an info message without throwing.

typescript
await tasks.createScheduler("syncDeviceTokens")(
  { userId },
  { taskName: userId },
);

WARNING

It can take up to 4 hours before an identical task name is accepted again after a task completes.

2. Automatic Deduplication via useDeduplication

Set useDeduplication: true in your task definition to have task names automatically generated from the payload using an MD5 hash:

typescript
const definitions = {
  collectFlightData: {
    schema: z.object({ flightId: z.string() }),
    options: {
      useDeduplication: true,
    },
  },
};

// No taskName needed — it's generated from the payload
await tasks.createScheduler("collectFlightData")({ flightId: "FL123" });

3. Deduplication Windows

Configure deduplicationWindowSeconds to combine deduplication with delayed execution:

typescript
const definitions = {
  recalculatePendingUpdates: {
    schema: z.object({ reviewId: z.string() }),
    options: {
      deduplicationWindowSeconds: 10,
    },
  },
};

When a deduplication window is configured:

  • The task is scheduled to execute after the specified number of seconds
  • useDeduplication is implicitly set to true
  • A time window boundary suffix is added to the task name, preventing collisions across different windows

4. No Deduplication

If you don't provide a taskName, useDeduplication is false, and deduplicationWindowSeconds is not configured, Cloud Tasks treats every task as unique.

Deduplication Windows Explained

Using a deduplication window is comparable to a debounce, with the key difference being that a task executes every N seconds rather than waiting for input to stop. The first scheduled task always executes after the time window has passed.

This is useful when an incoming event triggers an expensive operation that should not execute in short intervals, and you have no control over the rate of incoming events.

Example: A Firestore trigger fires on every document write in a collection. Each write schedules a recalculation task with a 10-second deduplication window. Even if 100 writes happen in 10 seconds, only one recalculation runs.

Configuration Summary

ConfigurationDeduplicationDelayedTask Name
No optionsNoneNoAuto-generated by GCP
taskName in schedulerManualNoProvided explicitly
useDeduplication: trueAutomatic (MD5)NoGenerated from payload
deduplicationWindowSeconds: NAutomatic (MD5 + time suffix)Yes (N seconds)Generated from payload + window

Released under the MIT License.