Skip to main content
@durable-effect/jobs provides durable job primitives for Cloudflare Workers. Write business logic as Effect programs while the framework handles durability, retries, and scheduling — all backed by Durable Objects.

What are durable jobs?

Durable jobs are long-lived processes that survive worker restarts. Unlike a regular serverless function that runs once and exits, a durable job maintains persistent state and a durable alarm schedule across restarts, crashes, and deployments. Each job instance runs in its own Durable Object, giving it:
  • Persistent state — survives process restarts
  • Durable alarms — scheduling survives crashes
  • Automatic retry — configurable backoff strategies
  • Type-safe client — full TypeScript inference from your schemas

Workflows vs. jobs

Durable workflows are long-running multi-step processes that orchestrate other services and wait for external events — they model a sequence of steps. Durable jobs are different: they are recurring or event-driven processes that maintain their own state and execute logic on a schedule or in response to events. Use jobs when you need background work that repeats or reacts, rather than a one-time multi-step workflow.

Job types

Job typePurposeUse cases
ContinuousRecurring work on a fixed scheduleToken refresh, health checks, daily reports
DebounceBatch rapid events before processingWebhook coalescing, update batching
TaskEvent-driven state machineOrder workflows, multi-step processes

Continuous

Run logic on a fixed interval or cron schedule.

Debounce

Collect events into batches before processing.

Task

Build event-driven state machines with full lifecycle control.

Common capabilities

All three job types share the following capabilities.

Persistent state

State is stored in Durable Object storage and validated using Effect Schema. Invalid state throws a ValidationError.
import { Schema } from "effect";

const stateSchema = Schema.Struct({
  count: Schema.Number,
  lastRunAt: Schema.Number,
  lastError: Schema.optional(Schema.String),
});

Retry configuration

Configure automatic retries for execution failures using Backoff strategies from @durable-effect/core. Retries are scheduled via durable alarms so they survive restarts.
import { Backoff } from "@durable-effect/core";

retry: {
  maxAttempts: 3,
  delay: Backoff.exponential({ base: "1 second", max: "30 seconds" }),
  jitter: true,
}

Type-safe client

JobsClient is fully typed from your job definitions — job names, event schemas, and state types are all inferred.
const client = JobsClient.fromBinding(env.JOBS);
const { state } = yield* client.continuous("tokenRefresher").getState("user-123");

Getting started

Cloudflare setup

Configure your worker, Durable Object binding, and wrangler.jsonc.

Client API

Start, trigger, and inspect job instances from your worker.

Build docs developers (and LLMs) love