ironalarm
bun install ironalarm

Reliable task scheduling for Cloudflare Durable Objects

Implementing the "reliable runNow" pattern for resilient long-running tasks with automatic checkpoint recovery.

Problem

Cloudflare Durable Objects can evict your code after ~144 seconds of inactivity. For long-running operations (like AI agent loops), a single eviction mid-task breaks your workflow. ironalarm solves this with a lightweight, userspace implementation that persists task state and uses a 30-second safety alarm net—if evicted, the task automatically retries and resumes from checkpoints.

Features

Reliable execution

runNow() starts immediately with 30s safety alarm for eviction recovery

Checkpoints

User-managed progress tracking for resumable work after evictions

Named handlers

Register task handlers by name—no function serialization required

Minimal

~300 LOC, zero dependencies, fully serializable tasks

Quick Start

import { ReliableScheduler } from 'ironalarm';

export class MyDO {
  private scheduler: ReliableScheduler;

  constructor(state: DurableObjectState, env: any) {
    this.scheduler = new ReliableScheduler(state.storage);

    this.scheduler.register('my-task', async (sched, taskId, params) => {
      if (!await sched.getCheckpoint(taskId, 'started')) {
        await doWork(params);
        await sched.checkpoint(taskId, 'started', true);
      }
      await expensiveOperation();
      await sched.completeTask(taskId);
    });
  }

  async alarm() {
    await this.scheduler.alarm();
  }

  async startTask(params: any) {
    const taskId = crypto.randomUUID();
    await this.scheduler.runNow(taskId, 'my-task', params);
  }
}

API Reference

Constructor

new ReliableScheduler(storage: DurableObjectStorage)

Creates a new scheduler instance with the provided Durable Object storage.

Methods

register(taskName: string, handler: Function)

Register a named task handler. The handler receives the scheduler, taskId, and params.

runNow(taskId: string, taskName: string, params?: any)

Start a task immediately with eviction safety. Sets a 30s safety alarm for automatic retry.

schedule(at: number, taskId: string, taskName: string, params?: any)

Schedule a task to run at a future time (Unix timestamp).

checkpoint(taskId: string, key: string, value: any)

Save progress for a task. Use this to mark completion of expensive operations.

getCheckpoint(taskId: string, key: string)

Retrieve saved progress for a task. Returns undefined if not found.

completeTask(taskId: string)

Mark a task as complete and clean up its state.

alarm()

Call this from your Durable Object's alarm handler to process scheduled tasks.

Interactive Demo

Start a Task

Simulates a long-running agent task with checkpoints: research → analysis → synthesis → writeup. Set duration from 1 second to 1 year.

Running Tasks

No tasks yet. Start one above to see the scheduler in action!

Design

  • Eviction safety: 30s safety alarm retries if evicted
  • Checkpoints: Skip already-done work on resume
  • Named handlers: No function serialization needed
  • Single queue: One alarm drives all tasks