Skip to main content
Tasks are persistent named timers. Each task names a method on your class; when the timer fires, the SDK calls that method with the task’s payload. All of it rides the actor’s single alarm slot, re-armed to the earliest pending deadline.
All three create the same kind of task and differ only in when the timer first fires: queue() as soon as possible, schedule() once after a delay, every() on a fixed interval. Reach for a task whenever work doesn’t have to finish inside the inbound call: an inbound method has a 30-second budget, while a task runs in the alarm turn with a budget on the order of minutes — so the pattern for LLM and outbound API work is record intent, queue() the work, return immediately. How Agents Run walks through that loop; budgets live in Limits.

queue()

protected queue(method, payload?, opts?): Promise<string>
Schedule a persistent task to run as soon as possible — identical to schedule(0, method, payload, opts). The canonical “think in the background” move: append to history in the inbound method, queue() the slow work, return immediately. Same dispatch, retry, and idempotency semantics as `schedule`. Parameters Returns Promise<string> The task id.

schedule()

protected schedule(delaySeconds, method, payload?, opts?): Promise<string>
Schedule a persistent task to run once, delaySeconds from now. A task names a method on your class: when the timer fires, the SDK calls this[method](payload) — one argument, the payload. If no such method exists, `onTask` fires instead. Tasks are persistent: they survive crashes and restarts, riding the actor’s single alarm slot. Delivery is at-least-once — write handlers to be idempotent. A task that throws is retried with exponential backoff (starting around a second, capped at 5 minutes) up to opts.maxRetries times after the first delivery (default 5), then parked (dropped without firing again). With a stable opts.id, scheduling is an upsert — the prior task with that id is replaced and the timer re-armed. Payloads must be storage-codec-safe or a CodecError is thrown. Parameters Returns Promise<string> The task id (pass to `cancelSchedule`).

every()

protected every(intervalSeconds, method, payload?, opts?): Promise<string>
Schedule a persistent task to run repeatedly at a fixed interval. The first fire is intervalSeconds from now. After each successful run the next fire is scheduled one interval from the start of the drain turn, and the attempt counter resets. Failed runs retry with backoff like any other task. Use a stable opts.id to make re-arming an upsert (e.g. on every activation). Parameters Returns Promise<string> The task id.

ScheduleOptions

Options for schedule()/queue()/every(). Properties everyMs?
optional everyMs?: number
Recurrence interval in ms. Set by every(); re-inserts the next fire.
id?
optional id?: string
Stable id. Re-scheduling with the same id replaces the prior task (dedup + re-arm). Omit for a random id. Must not contain a codec-unsafe value; keep it a plain string.
maxRetries?
optional maxRetries?: number
Retries AFTER the first delivery before the task is parked (dropped). Default 5, so a task runs up to maxRetries + 1 times total.

Dispatch

  • A due task calls this[task.name](task.payload) — one argument, the payload.
  • If no such method exists, the fallback fires instead: onTask(name, payload, { attempt }).
  • Task methods are ordinary methods. A method that should be schedulable but not RPC-callable from a stub can be named with a leading _ — the runtime excludes _-names from RPC, but the scheduler still dispatches to them.

onTask()

protected onTask(_name, _payload, _ctx): Promise<void>
Hook: fallback for a due task whose name is not a method on the subclass. The common path dispatches straight to the named method; this fires only when that lookup misses. The default implementation does nothing (the task is treated as delivered). Parameters Returns Promise<void>

now()

protected now(): number
Time source for the scheduler. Override in tests for a deterministic clock; every scheduling decision (queue / schedule / every / task draining) reads time through it. Returns number The current time in epoch milliseconds. Default Value Date.now()

Failure and retries

  • A task that throws is retried with exponential backoff (starting around a second, capped at 5 minutes), up to maxRetries times after the first delivery — 6 runs total by default.
  • A task that exhausts its retries is parked: deleted without firing again, and there is no callback when that happens.
  • A recurring (every) task resets its attempt count after each successful run, and schedules its next fire from the start of the drain turn (the timestamp captured before dispatch), not from when the method returns.

Delivery contract

Delivery is at-least-once: a crash after your method runs but before the task is marked done re-runs it on the next activation. Write task handlers to be idempotent — the same rule as alarm handlers. Payloads are stored in the actor’s persistent storage and must be codec-safe — JSON-native values plus Date, Map, Set, ArrayBuffer/TypedArray, BigInt, RegExp. Functions, class instances, or circular references throw a CodecError — see Errors.

cancelSchedule()

protected cancelSchedule(id): Promise<boolean>
Cancel a pending task by id. Removes the task and re-arms the alarm to the next remaining deadline. Parameters Returns Promise<boolean> true if a pending task was removed; false if no task with that id exists.

listSchedules()

protected listSchedules(): Promise<TaskRecord[]>
List every pending task on this agent. Returns Promise<TaskRecord[]> One TaskRecord per pending task — id, method name, payload, next due time, recurrence, and retry counters.

TaskRecord

A persistent scheduled task, as returned by listSchedules(). Properties attempts
attempts: number
Consecutive failed deliveries so far; resets after a successful recurring run.
createdAt
createdAt: Date
When the task was first scheduled.
due
due: number
Epoch ms at which the task becomes due.
everyMs?
optional everyMs?: number
Recurrence interval in ms, if this is a repeating task.
id
id: string
The task id — random unless a stable id was supplied at scheduling time.
maxRetries
maxRetries: number
Retries allowed after the first delivery before the task is parked.
name
name: string
The method name the task will call when it fires (or the name handed to the onTask fallback if no such method exists).
payload?
optional payload?: unknown
Arbitrary payload. MUST be codec-safe (JSON-native + Date/Map/Set/ ArrayBuffer/TypedArray/Buffer/BigInt/RegExp) — it is stored via ctx.storage.put, which throws CodecError on functions, class instances, or circular refs.