0.42 RC Layered sandboxes for agent-written apps →

Durable workflows you can trust an agent with

Obelisk is a fast, open-source, deterministic workflow runtime. Write workflows in JavaScript with no build step, or in Rust when performance matters.

  • Single binary
  • SQLite or Postgres
  • Crash resilient
  • Open source

From zero to a durable app in three steps

Install
curl -L --tlsv1.2 -sSf https://raw.githubusercontent.com/obeli-sk/obelisk/main/download.sh | bash -s -- v0.42.0-rc.8

Installs the Obelisk 0.42 release candidate. See Install for Docker, Nix, and other options.

Author
obelisk generate new my-app

The generated app has a webhook, a durable workflow, and an HTTP activity:

import { run } from "starter:app/workflow";

export default function handle() {
  const status = run();
  return new Response(`example.com returned HTTP ${status}\n`);
}

The webhook endpoint serves GET /run and calls the workflow. Learn more about webhook endpoints →

import { fetchStatus } from "starter:app/activity";

export default function run() {
  return fetchStatus();
}

The workflow is deterministic. Every child call and its result is persisted, so after a crash it replays and continues where it left off. Learn more about workflows →

export default async function fetchStatus() {
  const response = await fetch("https://example.com/");
  return response.status;
}

Activities perform side effects such as HTTP calls and are retried automatically on failure. Learn more about activities →

[[activity_js]]
name = "fetch_status"
location = "activity/fetch-status.js"
ffqn = "starter:app/activity.fetch-status"
params = []
return_type = "result<u32, string>"

[[activity_js.allowed_host]]
pattern = "https://example.com"
methods = ["GET"]

[[workflow_js]]
name = "run"
location = "workflow/run.js"
ffqn = "starter:app/workflow.run"
params = []
return_type = "result<u32, string>"

[[webhook_endpoint_js]]
name = "webhook"
location = "webhook/handle.js"
routes = [{ methods = ["GET"], route = "/run" }]

The deployment wires the components together and declares their typed signatures. No build step is needed. Learn more about deployment configuration →

app_name = "my-app"

# The app admin reviews which external requests a deployment may make.
[[outbound_http.allowed_host]]
pattern = "https://example.com"
methods = ["GET"]

The app config sets the upper bound on what any deployment of the app may access. Learn more about app configuration →

Building with a coding agent? Point it at llms.txt, which links every docs page and lists the recommended authoring path.

Run
cd my-app
obelisk server run --app-config app.toml --deployment deployment.toml
# in another terminal
curl localhost:9090/run

Use Web UI at :8080, Webhooks at :9090, API at :5005 or CLI to interact with the deployed application.

See every step in the Web UI

Why Obelisk?

Crash-Resilient Workflows

Every call, sleep, and result is persisted to the execution log. Crash mid-workflow — it resumes from the last completed step on restart.

Simple Architecture

Single binary, embedded SQLite or Postgres. No brokers, no sidecars, no YAML pipelines.

Sanity for the Age of AI

Claw-like agents blur planning and side effects into an opaque, breach-prone tangle. Obelisk keeps them strictly separate: deterministic execution, contained secrets, full audit trail.

Frequently Asked Questions

Why are deterministic workflow runtimes awesome?

Workflows are long-running, crash-resilient functions. The runtime persists every step — so a workflow can pause for days or months, survive server restarts, and always resume exactly where it left off.

What is the difference between a workflow and an activity?

A workflow is pure orchestration logic — deterministic and side-effect-free. An activity does real work: HTTP calls, file I/O, database writes. Activities must be idempotent so the runtime can retry them safely on failure.

What does determinism mean in the context of a workflow runtime?

The runtime records all non-deterministic calls — random values, timestamps, child results — to the execution log. On crash recovery, the workflow replays from the log, so the same inputs always produce the same execution path.

When does a code change break determinism?

Only when it changes the sequence of recorded events. Refactoring, adding log statements, or changing logic that runs after the last recorded event is safe.

What happens when the system crashes?

Workflows restart and replay completed steps from the execution log. In-progress activities are retried; finished ones return their recorded results — no work is lost.

How to handle cleanup after a permanent activity failure?

Invoke a compensating activity from the workflow to roll back side effects — the saga pattern. The workflow catches the failure and always runs cleanup before exiting.

What is the relation to AI?

AI-generated workflows are non-deterministic at authoring time — the same prompt can produce different logic on different runs. Obelisk enforces a strict separation between workflow design and execution: once deployed, every step is deterministic and recorded. When something goes wrong, the execution log — events, responses, child executions, logs, and source code, accessible via Web UI, REST, or CLI — answers exactly why it happened. This auditability and predictability stands in sharp contrast to today's agentic tools, where planning and side effects blur together.