Registry / workflow / dbos
library2.23.0pypypi✓ verified 87d ago

DBOS provides an ultra-lightweight Python library for durable execution, enabling fault-tolerant workflows and queues built on PostgreSQL (or SQLite by default). It allows developers to add resumable execution to applications using simple function annotations, eliminating the need for separate workflow orchestrators or task queue systems. As of version 2.18.0, it offers features like exactly-once execution, scheduled jobs, and built-in observability. The library is actively maintained with frequent updates and is suitable for building reliable backend services, data pipelines, and AI agents.

pip install dbos
INSTALL
IMPORT
SIG · DBOS
D
dbos
workflowpythonv2.23.0
Install
8.9s avg
Import
2023ms
Disk
104MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v2.23.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.940 runs
installs and imports cleanly · install 0.0s · import 2.090s · 91.6MB
glibc
py 3.103.940 runs
installs and imports cleanly · install 8.9s · import 1.956s · 94MB
104MB installed
● package 104MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

DBOS
from dbos import DBOS

This quickstart demonstrates a basic durable workflow using DBOS. It defines a `step` function and a `workflow` function, both decorated with DBOS annotations. The `DBOS` instance is initialized, optionally configured with a PostgreSQL connection string via the `DBOS_SYSTEM_DATABASE_URL` environment variable (defaults to SQLite). The `launch()` method registers the decorated functions, and `start()` initiates a workflow. DBOS automatically checkpoints the workflow's state, allowing it to recover from failures and resume from the last completed step upon restart.

import os import time from dbos import DBOS # Configure DBOS to use SQLite by default, or PostgreSQL if env var is set # For production, PostgreSQL is recommended. SQLite is good for local development. dbos_system_database_url = os.environ.get( 'DBOS_SYSTEM_DATABASE_URL', 'sqlite:///dbos_system.db' ) # Initialize DBOS (this should typically happen once at application startup) dbos_instance = DBOS(system_database_url=dbos_system_database_url) @dbos_instance.step() def greet_step(name: str) -> str: """A simple durable step that returns a greeting.""" print(f"Executing greet_step for {name}...") time.sleep(0.5) # Simulate some work return f"Hello, {name}!" @dbos_instance.workflow() def greeting_workflow(person_name: str) -> str: """A durable workflow composed of a single step.""" print(f"Starting greeting_workflow for {person_name}...") result = greet_step(person_name) print(f"Greeting workflow finished with: {result}") return result if __name__ == "__main__": print(f"DBOS System Database: {dbos_system_database_url}") try: # Launch the DBOS application. This will discover and register workflows. dbos_instance.launch() # Start a workflow. DBOS ensures it will complete reliably. workflow_handle = greeting_workflow.start(person_name="World") # You can optionally wait for the workflow to complete and get its result final_result = workflow_handle.get_result() print(f"Workflow 'greeting_workflow' completed with result: {final_result}") # Demonstrate recovery: if you crash the app here, and restart, the workflow will resume # For example, comment out the line above and uncomment the sleep and crash below, then restart. # print("Sleeping for 10 seconds. Try to crash the app (Ctrl+C or kill) and restart it!") # time.sleep(10) # workflow_handle = greeting_workflow.start(person_name="RecoveredUser") # This will start a new one, but if the previous was pending, it would resume. except KeyboardInterrupt: print("Application interrupted.") except Exception as e: print(f"An error occurred: {e}") finally: # Properly shut down DBOS resources dbos_instance.destroy() print("DBOS application shut down.")
Debug
Known issues
breakingModifying the sequence or number of steps within an active workflow (a 'breaking change') can cause recovery failures for in-progress workflows. DBOS checkpoints the state of workflows in the database based on the expected flow.
fix
Use DBOS's patching (`DBOS.patch()`) or versioning strategies to safely deploy changes without disrupting existing long-running workflows. Consult the 'Upgrading Workflow Code' documentation.
affects: All versions
gotchaDBOS workflows must be deterministic: given the same inputs, they must always invoke the same steps in the same order with the same inputs and expect the same return values from those steps. Non-deterministic workflows can lead to incorrect recovery behavior and `DBOSUnexpectedStepError`s.
fix
Ensure all workflow logic (excluding decorated steps, which handle their own non-determinism) is deterministic. Avoid direct I/O or random number generation inside workflow functions.
affects: All versions
gotchaEmbedding synchronous (blocking) calls in Python or TypeScript asynchronous DBOS applications can block the event loop, preventing workflows and other async operations from making progress and leading to 'stuck' workflows.
fix
Ensure all potentially blocking operations within an async DBOS application are properly awaited or run in an executor (e.g., `loop.run_in_executor`).
affects: All versions
gotchaWhen using DBOS's retry mechanisms for steps that interact with external APIs, it's recommended to disable any built-in retry logic in the API client itself to avoid excessive or conflicting retries. For example, set `max_retries=0` for `OpenAIProvider` clients.
fix
Configure external API clients to have `max_retries=0` or similar to rely solely on DBOS's step retry policy.
affects: All versions
gotchaWorkflow inputs/outputs and step outputs are checkpointed using Python's `pickle` module. Ensure that all data passed through workflows or returned by steps is pickle-serializable. Large objects may also impact performance due to database write overhead.
fix
Verify that all data types used in workflow/step inputs/outputs are compatible with `pickle`. Keep payload sizes reasonable for optimal performance.
affects: All versions
gotchaDBOS requires the system database to be available at application startup. If the configured database is unreachable during initialization, DBOS will exit rather than waiting for the connection to be established.
fix
Ensure the PostgreSQL database (or SQLite file) is accessible before starting the DBOS application process. Implement infrastructure-level dependencies or retry mechanisms for application startup if database availability cannot be guaranteed.
affects: All versions
gotchaApplying multiple DBOS decorators (e.g., `@DBOS.workflow()` and `@DBOS.transaction()`) to the same function or registering functions with conflicting names/types will raise a `DBOSConflictingRegistrationError`.
fix
Each function should have a single primary DBOS decorator. Ensure unique names for functions registered with DBOS.
affects: All versions
Errors
Common errors & fixes
DBOSInitializationError: Failed to initialize DBOS
This error occurs when the DBOS client cannot initialize successfully, often due to issues like an invalid database connection string, inaccessible database, or problems creating the system database schema during startup.
fix
Ensure your `system_database_url` in `DBOSConfig` or `dbos-config.yaml` is correct and points to an accessible PostgreSQL or SQLite database, and that the application has the necessary permissions to create tables if they don't already exist. For PostgreSQL, run `dbos migrate` with a privileged user if automatic creation is failing.
DBOSConflictingWorkflowError: Workflow ID conflict
This error is raised when you attempt to start a new workflow with a `workflow_id` that already exists, but the new workflow's function name or arguments differ from the existing one. Workflow IDs must uniquely identify a specific workflow execution with its initial parameters.
fix
Provide a unique `workflow_id` for each distinct workflow execution, or ensure that if you are intentionally trying to retrieve or interact with an existing workflow, its function and arguments match the original.
Why am I seeing an error that function X was recorded when Y was expected?
This error indicates that your workflow function is non-deterministic. During recovery, DBOS attempts to re-execute steps, but finds a mismatch between the expected step (Y) and the step recorded in the database's checkpoint (X). This happens because the workflow logic took a different path during recovery than its initial execution.
fix
Ensure all DBOS workflow functions are deterministic. This means they must call the same steps in the same order with the same inputs when given the same initial workflow inputs and step return values. Any non-deterministic operations (like I/O, random numbers, current time) should be encapsulated within `@DBOS.step()` decorated functions, which DBOS checkpoints and skips re-execution of during recovery.
TypeError: cannot pickle <object>
DBOS uses `pickle` to serialize and store workflow inputs, outputs, and step outputs in the system database for durable execution and recovery. This error occurs when a non-serializable object (like a database connection, file handle, or complex custom object without proper `__reduce__` methods) is passed as a workflow input/output or a step output.
fix
Ensure that all inputs and outputs of workflows and outputs of steps are `pickle`-serializable. Avoid passing non-serializable objects directly. Instead, construct such objects (e.g., database connections, API clients) inside the workflow or step using serializable parameters, or store them globally if appropriate.
Upgrade
Version history
2.23.0latest on PyPI · released Jun 1, 2026
Audit
Dependencies
sqlalchemyrequiredORM for database interactions, core dependency.
psycopgoptionalPostgreSQL adapter, used when connecting to PostgreSQL. For SQLite, it's not strictly needed but a compatible DBAPI is.
python-dateutilrequiredFor cron specification parsing in scheduled workflows.
pyyamlrequiredFor parsing DBOS configuration files (e.g., dbos-config.yaml).
typer-slimrequiredFor CLI tooling.
websocketsrequiredFor monitoring and UI integration.
opentelemetry-apioptionalRequired for OpenTelemetry tracing features, installed with 'dbos[otel]'.
opentelemetry-sdkoptionalRequired for OpenTelemetry tracing features, installed with 'dbos[otel]'.
Agent activity
48 hits · last 30 days
node
44
OpenAI (training)
1
Resources
dbos — pip install dbos · libregistry