Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

Satay Runtime

Satay is a local-first durable-execution runtime for async Python. You write ordinary async def workflows and tasks; Satay records every durable call to an append-only journal and, on crash, replays the workflow from the top — reusing recorded results and re-executing only what never finished. No external infrastructure: it runs in one process over SQLite.

import satay

@satay.task()
async def charge(amount: int) -> str: ...

@satay.workflow
async def checkout(order):
    receipt = await charge(order["total"])
    return receipt

The debugger — Satay Studio, a local web UI over an HTTP read API — ships in the optional satay[studio] extra, so applications that embed Satay never carry the FastAPI/uvicorn/JS stack into production.

Status

The MVP is built and the full suite is green (V1–V8). Trust the code over the docs: docs/ describes the intended full system, and where docs and code disagree the code wins. uv run pytest -q prints the current test count.

What works today:

  • Durable core + replay. Workflows replay from the top against an append-only SQLite journal (PRAGMA user_version schema, forward-only migrations, WAL); recorded results are reused and only unfinished work re-executes.
  • Execution guarantees. Retries with capped exponential backoff and jittered delays off an injected clock, at-least-once task execution, runtime-derived idempotency keys readable inside a task body, replay nondeterminism detection, and an effect_safety policy that guards retryable side-effecting tasks.
  • Time and events. Durable sleep, wait_for_event/send_event over a persistent inbox, and a timer + event poll loop with FIFO delivery and event-wins-over-timeout.
  • Composition. map, gather, and start_child, each item a keyed durable call, so a crash mid-fan-out resumes with completed items reused and only unresolved items re-run.
  • Control plane. An HTTP control + read API (start, cancel, send event, fork; run list, timeline, tree, task detail, compare) with a redactor applied to every read and a loopback/token security guard.
  • Studio. The Satay Studio SPA ships as a built bundle served by the same process.
  • Forking and versioning. Fork a run from a prefix, compare two runs call-by-call, and a code-version stamp with a strict/warn/off mismatch policy on resume.
  • satay dev. One command brings up the lock, store, worker, and Studio server, and tears them down in reverse.
  • Payload spill. Encoded payloads over 256 KiB spill to content-addressed blob files transparently on write and rehydrate on read.

Deliberate MVP gaps, so the honesty survives contact:

  • No blob GC. No run deletion and no compaction; blobs accumulate under ./.satay/ and removal is manual (ADR-0004). A future GC has to be reference-aware, since forks share blobs with their source run.
  • Fan-out is fail-fast only. No collect / return_exceptions mode for map/gather/start_child; the first failure raises and sibling results are discarded (ADR-0020).
  • satay runs show is frozen at the V1 event subset (ADR-0016). Timer, event, cancellation, and fork events render as bare type lines; Studio covers the rest.
  • Fork only accepts terminal runs (ADR-0004) — completed, failed, or cancelled.
  • One process, one writer. No PostgreSQL backend, no multi-worker or distributed execution. The cross-process data-dir lock is POSIX flock and only satay dev takes it.
  • Async only. Sync (non-async) workflows and tasks are unsupported.
  • Nondeterminism detection is runtime-only and compares the durable-call schedule, not arguments; there is no static analysis of workflow bodies, and no automatic migration of long-running workflows across code versions.
  • Windows is best-effort and SQLite on network filesystems is unsupported (ADR-0019).

See docs/ for the specs and CLAUDE.md for the build brief.

Requirements

  • Python 3.12 or 3.13
  • uv for environment and dependency management
  • Linux/macOS first-class; Windows best-effort (SQLite on local disk only)

Dev quickstart

uv sync                              # create the venv, install deps + dev group
uv run ruff check .                  # lint
uv run ruff format --check .         # format check
uv run mypy src                      # type-check (strict)
uv run pytest tests/unit -q          # unit tests

The integration and e2e tests that cover Studio and the HTTP API need the studio extra; without it they skip themselves and the reported count silently drops:

uv sync --extra studio               # then run the full suite
uv run pytest -q

Or via the Makefile:

make dev      # uv sync
make check    # ruff + mypy
make test     # unit tests
make ci       # everything CI runs

Install the pre-push hook (runs the cheap gates before every push):

make install-hooks            # or: ./scripts/install-hooks.sh

Layout

src/satay/        runtime core (pure Python, near-zero dependencies)
  api/            author decorators, primitives, run handle, TaskContext
  replay/         replay engine, identity, nondeterminism
  journal/        event model + Store seam + codec
  executor/       TaskExecutor seam + LocalTaskExecutor
  timers/         timer + event poll loop
  control/        HTTP control + read API   (satay[studio])
  versioning/     code-version stamper
  blobs/          payload spill
  devstack/       `satay dev` orchestrator  (satay[studio])
  testing/        fault injection, manual clock, seeded RNG, fixtures
  cli/            core argparse CLI (`satay runs show`)
tests/{unit,integration,e2e}/
docs/             specs + ADRs

License

Apache-2.0. See LICENSE.

Release files for satay 0.1.0a1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for satay 0.1.0a1
File Size Uploaded
satay-0.1.0a1.tar.gz 113.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for satay 0.1.0a1
File Interpreter ABI Platform
satay-0.1.0a1-py3-none-any.whl Python 3 none any Details

Total release size: 250.6 kB

Release files / satay-0.1.0a1.tar.gz

Download URL satay-0.1.0a1.tar.gz
Size 113.8 kB
Tags Source
SHA-256 checksum
How to use checksums
3e4a591826b49b1ce670a863dcef1b02090772ad81d984c7d48d09fa42a7a3d6
BLAKE2b-256 checksum
How to use checksums
e66b56c9d2947136cf9a6c49fa73dca371e03e35a57a2a4d25e39768e487d189
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 30, 2026.

Transparency log

Release files / satay-0.1.0a1-py3-none-any.whl

Download URL satay-0.1.0a1-py3-none-any.whl
Size 136.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
191b29feec44ab9967bb21e52251dda029960e08eaed3aa9e5e3a0de234d8f67
BLAKE2b-256 checksum
How to use checksums
2ce6548ee9f2f4e984da93b86c4538b453db79c12dfaecda3f13d78e98835c6c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 30, 2026.

Transparency log
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page