Skip to main content

Why DBOS?

What is DBOS?

DBOS provides lightweight durable workflows built on top of Postgres. Instead of managing your own workflow orchestrator or task queue system, you can use DBOS to add durable workflows and queues to your program in just a few lines of code.

To get started, follow the quickstart to install the open-source library and connect it to a Postgres database. Then, annotate workflows and steps in your program to make it durable! That's all you need to do—DBOS is entirely contained in the open-source library, there's no additional infrastructure for you to configure or manage.

When Should I Use DBOS?

You should consider using DBOS if your application needs to reliably handle failures. For example, you might be building a payments service that must reliably process transactions even if servers crash mid-operation, or a long-running data pipeline that needs to resume seamlessly from checkpoints rather than restart from the beginning when interrupted.

Handling failures is costly and complicated, requiring complex state management and recovery logic as well as heavyweight tools like external orchestration services. DBOS makes it simpler: annotate your code to checkpoint it in Postgres and automatically recover from any failure. DBOS also provides powerful Postgres-backed primitives that makes it easier to write and operate reliable code, including durable queues, notifications, scheduling, event processing, and programmatic workflow management.

How Does DBOS Work?

DBOS workflows make your program durable by checkpointing its state in Postgres. If your program ever fails, when it restarts all your workflows will automatically resume from the last completed step.

For example, let's say you're running an e-commerce platform where an order goes through multiple steps:

Durable Workflow

This program looks simple, but making it reliable is deceptively difficult. For example, the program may crash (or its server may be restarted) after validating payment but before shipping an order. Alternatively, the shipping service may experience an outage, leaving the shipping step impossible to complete. In either case, the customer has been charged, but their order is never shipped.

DBOS makes these failures easier to recover from. All you have to do is annotate your program with decorators like @DBOS.workflow() and @DBOS.step():

@DBOS.step()
def validate_payment():
...

@DBOS.workflow()
def checkout_workflow()
validate_payment()
check_inventory()
ship_order()
notify_customer()

These decorators durably execute your program, persisting its state to a Postgres database:

Durable Workflow

You can think of this stored state as a checkpoint for your program. If your program is ever interrupted or crashes, DBOS uses this saved state to recover it from the last completed step. For example, if your checkout workflow crashes right after validating payment, instead of the order being lost forever, DBOS recovers from a checkpoint and goes on to ship the order. Thus, DBOS makes your application resilient to any failure.

Use Cases

DBOS helps you write complex programs in remarkably few lines of code. For example:

Write business logic in normal code, with branches, loops, subtasks, and retries. DBOS makes it resilient to any failure.

See an example ↗️

@DBOS.step()
def validate_payment():
...

@DBOS.workflow()
def checkout_workflow()
validate_payment()
check_inventory()
ship_order()
notify_customer()

DBOS vs. Other Systems

DBOS vs. Temporal

Both DBOS and Temporal provide durable execution, but DBOS is implemented in a lightweight Postgres-backed library whereas Temporal is implemented in an externally orchestrated server.

You can add DBOS to your program by installing the open-source library, connecting it to Postgres, and annotating workflows and steps. By contrast, to add Temporal to your program, you must rearchitect your program to move your workflows and steps (activities) to a Temporal worker, configure a Temporal server to orchestrate those workflows, and access your workflows only through a Temporal client. This blog post makes the comparison in more detail.

When to use DBOS: You need to add durable workflows to your applications with minimal rearchitecting, or you are using Postgres.

When to use Temporal: You don't want to add Postgres to your stack, or you need a language DBOS doesn't support yet.

DBOS vs. Airflow

DBOS and Airflow both provide workflow abstractions. Airflow is targeted at data science use cases, providing many out-of-the-box connectors but requiring workflows be written as explicit DAGs and externally orchestrating them from an Airflow cluster. Airflow is designed for batch operations and does not provide good performance for streaming or real-time use cases. DBOS is general-purpose, but is often used for data pipelines, allowing developers to write workflows as code and requiring no infrastructure except Postgres.

When to use DBOS: You need the flexibility of writing workflows as code, or you need higher performance than Airflow is capable of (particularly for streaming or real-time use cases).

When to use Airflow: You need Airflow's ecosystem of connectors.

DBOS vs. Celery/BullMQ

DBOS provides a similar queue abstraction to dedicated queueing systems like Celery or BullMQ: you can declare queues, submit tasks to them, and control their flow with concurrency limits, rate limits, timeouts, prioritization, etc. However, DBOS queues are durable and Postgres-backed and integrate with durable workflows. For example, in DBOS you can write a durable workflow that enqueues a thousand tasks and waits for their results. DBOS checkpoints the workflow and each of its tasks in Postgres, guaranteeing that even if failures or interruptions occur, the tasks will complete and the workflow will collect their results. By contrast, Celery/BullMQ are Redis-backed and don't provide workflows, so they provide fewer guarantees but better performance.

When to use DBOS: You need the reliability of enqueueing tasks from durable workflows.

When to use Celery/BullMQ: You don't need durability, or you need very high throughput beyond what your Postgres server can support.