Skip to main content

Durable Monty

⚠️ Experimental: This is an experimental project exploring a different approach to durable functions. Not recommended for production use yet.

Durable functions for Python. Write normal async/await code that pauses at gather(), executes tasks in parallel (even distributed), and resumes when done.

What Are Durable Functions?

Durable functions are workflows that survive crashes and restarts. Your code pauses when waiting for tasks, saves its state to a database, and resumes exactly where it left off when tasks complete - even if your process dies in between.

Perfect for: Long-running workflows, parallel task execution, distributed systems, background jobs.

How It Works

Powered by monty-python - a sandboxed Python interpreter that can pause and serialize execution state. When your code hits await gather(), Monty captures the exact execution state (~800 bytes), returns pending tasks, and later resumes from that exact point with results.

Result: Pure Python async/await that works like Temporal or AWS Step Functions, but simpler.

Why This Approach Is Simpler

Other frameworks (Temporal, Durable Functions, etc.):

  • Re-execute your entire function from the start on every resume
  • Use replay/event sourcing to return cached results for completed calls
  • Example: If your workflow pauses at step 7, resuming re-runs steps 1-6 (with cached results) before continuing
  • Requires deterministic code and careful side-effect management

Durable Monty:

  • Serializes the exact Python execution state (call stack, variables, everything)
  • No re-execution - just deserialize and continue from where you left off
  • True pause/resume - no replay, no determinism requirements, no special coding patterns
  • Simpler mental model: "save and restore" instead of "replay and cache"

Trade-offs:

  • Code versioning: Changing workflow code can break in-flight executions (serialized state expects compatible code)
  • Migration complexity: Updating workflows requires careful handling of existing executions
  • Less proven: Built on pydantic-monty, which is newer than battle-tested frameworks like Temporal
  • Python-only: Requires deep interpreter integration, unlike replay-based systems that work with any language

The main practical challenge: if you iterate quickly on workflow code, in-flight executions may break on deployment. Consider draining executions before code changes or using versioned workflows.

from durable_monty import init_db, OrchestratorService, Worker, LocalExecutor

def process(item):
    return f"processed_{item}"

code = """
from asyncio import gather
results = await gather(
    process('a'),
    process('b'),
    process('c')
)
results
"""

service = OrchestratorService(init_db())
# Pass function object - full path derived automatically
exec_id = service.start_execution(code, [process])

# Process until complete
worker = Worker(service, LocalExecutor())
worker.run(until_complete=True)

# Get the result
output = service.get_result(exec_id)
print(output)  # ['processed_a', 'processed_b', 'processed_c']

Install

uv add durable-monty

How It Works

  1. Code hits gather() → pauses and saves state (~800 bytes)
  2. Creates pending calls in database
  3. Worker picks them up and executes in parallel
  4. When all complete → resumes and returns result

State survives restarts. Parallel execution. Pure Python.

Distributed Execution

Redis Queue:

uv add durable-monty --extra rq
from durable_monty.executors.rq import RQExecutor

worker = Worker(service, RQExecutor())
worker.run()

# Start RQ workers: rq worker durable-monty

Event-driven (Lambda, Modal):

uv add durable-monty --extra api
from durable_monty.api import create_app
import uvicorn

app = create_app(service)
uvicorn.run(app, port=8000)

# Executors POST results to: /webhook/complete

Examples

  • examples/with_worker.py - Local execution
  • examples/with_rq.py - Redis Queue
  • examples/with_webhook.py - Webhooks

Development

git clone https://github.com/koenvo/monty-durable
cd monty-durable
uv sync
uv run pytest

License

MIT

Metadata

Release files for durable-monty 0.1.5

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

Source distribution (sdist)

Source distribution for durable-monty 0.1.5
File Size Uploaded
durable_monty-0.1.5.tar.gz 62.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for durable-monty 0.1.5
File Interpreter ABI Platform
durable_monty-0.1.5-py3-none-any.whl Python 3 none any Details

Total release size: 78.6 kB

Release files / durable_monty-0.1.5.tar.gz

Download URL durable_monty-0.1.5.tar.gz
Size 62.6 kB
Tags Source
SHA-256 checksum
How to use checksums
91146072fcbaa0b83362d1a447786b60e701e7aabb8307df252dbad4f00dd805
BLAKE2b-256 checksum
How to use checksums
ab4091864c4ab3d926052d5f613cdf65b7dd497c554e067da3abb837c14c946a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Feb 10, 2026.

Transparency log

Release files / durable_monty-0.1.5-py3-none-any.whl

Download URL durable_monty-0.1.5-py3-none-any.whl
Size 15.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
63df22cdd98a8e9602383e934e52ed3f09cc1263b437cae827b83a131f49ec5e
BLAKE2b-256 checksum
How to use checksums
40bb2aad0c46e2e520ed8dc59c917f6331fe4494763c3cb6dd4aae169b5c9208
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Feb 10, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.5 This release

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

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