Tsumugi Docs
Search

INFO

This page was translated by an LLM. Some details and nuances may differ from the original.

Enqueuing Jobs

Enqueue Methods

MethodTypeSource of shard count and execution settings
tsumugi.enqueue / tsumugi.jobs(env)Payload and required-key types derived for each bindingbindings of defineTsumugi
createClient(bindings)binding is string, payload is unknownFirst argument of createClient

From the same Worker as the performer, enqueue jobs using the return value of defineTsumugi.
createClient is a client for enqueuing jobs from a Worker that has no performer.

If a required binding is missing, tsumugi.enqueue, tsumugi.enqueueMany, and tsumugi.jobs(env) throw an exception.
The exception includes a list of the missing bindings.
JOB_SHARD, TSUMUGI_DB, and TSUMUGI_QUEUE are always required.
Add RUN if you use flows, and add SCHEDULER if you use schedules.
For a remote() performer, provide the corresponding Service Binding.

enqueue

const id = await tsumugi.enqueue(env, {
  binding: 'MAIL',
  payload: { to: 'a@example.com', subject: 'hi' },
});

The return value is the job ID.
The type of the payload is derived from the value of the specified binding.
If you omit a required key, a compile error occurs.

enqueueMany

tsumugi.enqueueMany enqueues multiple jobs in a batch.

const ids = await tsumugi.enqueueMany(env, [
  { binding: 'MAIL', payload: { to: 'a@example.com', subject: 'hi' } },
  { binding: 'MAIL', payload: { to: 'b@example.com', subject: 'hi' } },
]);

The time required barely changes as the number of jobs grows.
In the returned array, the i-th element is the ID that corresponds to the i-th job in the input.

jobs

The return value of tsumugi.jobs(env) is a typed job-enqueuing object with env specified in advance.

const jobs = tsumugi.jobs(env);

const id = await jobs.enqueue('MAIL', { to: 'a@example.com', subject: 'hi' });
await jobs.enqueue('CHARGE', { customerId: 'c1', amountJpy: 1200 }, { concurrencyKey: 'customer:c1' });

What gets enqueued is identical to tsumugi.enqueue.
The only difference is the form of the arguments.
For a performer with required keys, a compile error occurs if you omit options or if you do not specify the key.

Options

NameDefaultDescription
priority0Numeric priority. Larger values run first
maxAttempts3Maximum number of attempts. An integer of 1 or more
backoffExponential, starting at 1 second, factor 2, cap 1 hour, with jitterInterval between retries
timeoutMs60000Time until timeout
delayMsNoneDelay before execution starts. Cannot be specified together with runAt
runAtNoneTime at which execution starts. Cannot be specified together with delayMs
expiresInMsNoneExpiration counted from the enqueue time
expiresAtNoneExpiration time. Takes precedence over expiresInMs
guaranteeat-least-onceExecution guarantee. Use at-most-once to avoid duplicate execution
concurrencyKeyNoneKey for running jobs with the same key in order
uniqueKeyNoneKey for deduplication
uniqueForMs24 hoursPeriod during which uniqueKey is used to detect duplicates
partitionKeyNoneKey that determines the destination when shards are split
traceparentNoneW3C Trace Context of the enqueuer

For a binding with two or more shards, omitting partitionKey throws an exception.
Selecting the destination shard by partitionKey applies only to enqueue methods that apply shards from bindings.
See Enqueue Methods for details.

Scheduled Execution

// 1 hour later
await tsumugi.enqueue(env, { binding: 'MAIL', payload, delayMs: 60 * 60 * 1000 });

// At a specified time
await tsumugi.enqueue(env, { binding: 'MAIL', payload, runAt: Date.parse('2026-08-01T09:00:00+09:00') });

Expiration

If you specify expiresInMs or expiresAt, a job past its expiration is not executed and transitions to CANCELLED.
Even after a pause or an execution delay, expired notifications are not executed all at once.

// Do not run if it cannot start within 5 minutes
await tsumugi.enqueue(env, { binding: 'NOTIFY', payload, expiresInMs: 5 * 60 * 1000 });

A running job is not interrupted even after its expiration passes.
If the next scheduled retry time is later than the expiration, the job transitions to CANCELLED on failure.
The expiration also applies when you manually retry FAILED and STALLED jobs.

Deduplication

If you specify uniqueKey and a job with the same key already exists, a new job is not created.
In this case, the return value is the ID of the existing job.

const id = await tsumugi.enqueue(env, {
  binding: 'SYNC',
  payload: { sku: 'X-1' },
  uniqueKey: 'sku:X-1',
});

A duplicate enqueue is not an error.
No exception is thrown either.
After the uniqueForMs period elapses, duplicate detection is lifted.
If you enqueue again with the same key, a new job is created.

Serialization

Jobs with the same concurrencyKey run concurrently up to the number set by perKeyConcurrency.
The default is 1, so jobs with the same key run one at a time, in order.

await tsumugi.enqueue(env, {
  binding: 'CHARGE',
  payload: { customerId: 'c1', amountJpy: 1200 },
  concurrencyKey: 'customer:c1',
});

For a binding with two or more shards, this serialization is limited to within the same shard for a given partitionKey.
See shard for details.

Trace Information

If you specify traceparent when enqueuing, the same value is passed to ctx.traceparent in the performer.
The same value is passed on retries, and the dashboard shows this value in the job details.
enqueueMany accepts a traceparent for each job.

await tsumugi.enqueue(env, {
  binding: 'MAIL',
  payload: { to: 'a@example.com', subject: 'hi' },
  traceparent: '00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01',
});

The format is W3C Trace Context version 00 (55 characters).
Write each field in lowercase hexadecimal.
If you specify a malformed value, a validation error occurs at enqueue time.
A validation error also occurs if every digit of the trace-id or the parent-id is 0.

Job ID

<binding>#<shard>:<localId>

Example: MAIL#0:xxxxxxxxxxxxxxxxxxxxxxxx

Even if you change the number of shards, existing job IDs still identify the same jobs.
However, the destination shard of jobs with the same partitionKey value may differ before and after the change.
Control by concurrencyKey and uniqueKey is performed per shard, so it does not apply between jobs whose destination shards differ.
If you reduce the number of shards, runtime configuration changes are not applied to the shards that fall out of range.
For details on shards, see shard.

Enqueuing from Another Worker

For enqueuing from a Worker that has no performer, see Enqueuing from Another Worker.

Edit this page

Published: Last updated: