> ## Documentation Index
> Fetch the complete documentation index at: https://developers.telnyx.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Scheduling

> queue, schedule, every — durable named timers over the actor's alarm slot, with retries, backoff, and at-least-once delivery.

Tasks are durable 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](/docs/edge-compute/stateful-actors/alarms) slot, re-armed to the
earliest pending deadline.

## Creating tasks

| Method                                       | Semantics                                                               |
| -------------------------------------------- | ----------------------------------------------------------------------- |
| `queue(method, payload?, opts?)`             | Run as soon as possible — identical to `schedule(0, ...)`               |
| `schedule(seconds, method, payload?, opts?)` | Run once, `seconds` from now                                            |
| `every(seconds, method, payload?, opts?)`    | Run repeatedly at a fixed interval; throws if `seconds` is not positive |

All three return `Promise<string>` — the task id.

```ts theme={null}
await this.queue("process", { attempt: "first" });
await this.schedule(3600, "sendReminder");
await this.every(300, "checkStatus");
```

### `ScheduleOptions`

```ts theme={null}
interface ScheduleOptions {
  id?: string;         // stable id: re-scheduling REPLACES the prior task (dedup)
  maxRetries?: number; // retries after the first delivery; default 5
}
```

With a stable `id`, scheduling is an upsert — the prior task with that id is replaced
and the timer re-armed. Without one, every call creates a new task under a random id.

## 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.

## 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](/docs/edge-compute/stateful-actors/alarms).

Payloads are stored in the actor's durable 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](/docs/edge-compute/stateful-actors/api-reference/errors).

## Inspecting and cancelling

| Method               | Returns                 | Semantics                                    |
| -------------------- | ----------------------- | -------------------------------------------- |
| `cancelSchedule(id)` | `Promise<boolean>`      | Remove a pending task; `false` if no such id |
| `listSchedules()`    | `Promise<TaskRecord[]>` | Every pending task record                    |

```ts theme={null}
interface TaskRecord {
  id: string;
  name: string;        // the method it will call
  payload?: unknown;
  due: number;         // epoch ms of the next fire
  everyMs?: number;    // recurrence interval, if repeating
  attempts: number;    // consecutive failed deliveries so far
  maxRetries: number;
  createdAt: Date;
}
```
