Now with checkpoint recovery

Effect-TS powered task scheduling for
Cloudflare Durable Objects

Composable, resilient long-running tasks with automatic checkpoint recovery, structured concurrency, and dependency injection. Production-ready for AI agents, workflows, and complex async operations.

$ bun install ironalarm
Try the demo

The 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

Effect-TS Powered

Composable effects with dependency injection and structured concurrency

Automatic Retries

Exponential backoff retry with Schedule.exponential for resilient execution

Fiber Concurrency

Non-blocking concurrent task processing with configurable limits

DO Sharding Ready

Hash-based routing for horizontal scaling across multiple DO instances

Tagged Error Types

Type-safe error handling with Data.TaggedError

Structured Logging

Built-in observability with Effect.log* for production monitoring

Quick Start

      import { ReliableScheduler, SchedulerService } from 'ironalarm';
import { Effect } from 'effect';

export class MyDO {
  private scheduler: ReliableScheduler;

  constructor(state: DurableObjectState, env: any) {
    // Initialize with DO storage + concurrency limits
    this.scheduler = new ReliableScheduler(state.storage, {
      maxConcurrentTasks: 10
    });

    // Register Effect-powered task handler with dependency injection
    this.scheduler.register('my-task', (taskId, params) => {
      return Effect.gen(function* () {
        const svc = yield* SchedulerService;

        const started = yield* svc.getCheckpoint(taskId, 'started');
        if (!started) {
          yield* Effect.promise(() => doWork(params));
          yield* svc.checkpoint(taskId, 'started', true);
        }

        yield* svc.completeTask(taskId);
        yield* Effect.log('Task completed successfully');
      });
    });
  }

  async alarm() {
    // Process due tasks with structured concurrency
    await Effect.runPromise(this.scheduler.alarm());
  }
}
    

API Reference

All methods available on the ReliableScheduler class.

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 simulated long-running task and watch the checkpoint system in action.

Start a Task

Simulates a long-running agent task with checkpoints: researchanalysissynthesiswriteup

Running Tasks

0 completed 0 running 0 paused

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