Named alarms
A Durable Object has one physical alarm. Durability lets operations and multiple named logical alarms share it without replacing one another’s wake-ups.
Configure and schedule
Section titled “Configure and schedule”import { createDurability } from 'durability';import { exponential, jitter } from 'durability/utils';
export class ImageJobs extends DurableObject<Env> { private readonly durability = createDurability( this.ctx, { resizeImage: async ({ payload }) => this.env.IMAGES.resize(payload.imageId), }, { alarms: { cleanup: async ({ scheduledTime, attempt, idempotencyKey, signal, platform, }) => { await this.env.CLEANUP.fetch('https://cleanup.internal/run', { method: 'POST', headers: { 'Idempotency-Key': idempotencyKey }, signal, }); console.log({ scheduledTime, attempt, platform }); }, }, alarmMethods: { cleanup: { attemptTimeoutMs: 60_000, retries: { maxAttempts: 5, delay: (attempt) => jitter(exponential(attempt)), }, retryTimeouts: true, }, }, } );
scheduleCleanup() { return this.durability.alarm.cleanup(Date.now() + 5_000); }
alarm(info?: AlarmInvocationInfo) { return this.durability.alarm(info); }}Each key in alarms becomes a typed scheduler method on durability.alarm.
Replacement and concurrency
Section titled “Replacement and concurrency”Scheduling the same name again replaces its pending occurrence. If that name is already running:
- The active handler continues.
- The replacement remains pending and runs afterward.
- A single name never has overlapping handlers within one Durable Object instance.
- Different names can run concurrently.
A successful handler deletes only the occurrence it executed, so it cannot erase a replacement scheduled while it was running.
Handler information
Section titled “Handler information”| Field | Meaning |
|---|---|
name | Configured logical alarm name |
scheduledTime | Original timestamp supplied to the scheduler |
attempt | One-based attempt number |
isRetry | Whether this occurrence ran before |
retryCount | Number of completed previous attempts |
idempotencyKey | Stable key for every attempt of this occurrence |
signal | Attempt-scoped timeout signal |
platform | Cloudflare AlarmInvocationInfo, when supplied |
Each schedule gets a new internal occurrence ID and idempotency key.
Timeouts
Section titled “Timeouts”Named alarm timeouts are terminal by default because an external side effect may have completed before the caller stopped waiting. Set retryTimeouts: true only when the handler passes idempotencyKey to its side effects or can reconcile their outcome first.
If a timed-out handler ignores its signal, Durability holds the per-name execution lock until it actually settles. That prevents an overlapping retry.