dbos-transact-golang is a free, open source orchestration & scheduling project written in Go and released under MIT. It has 863 GitHub stars, 80 forks and 10 open issues, and was last pushed 4 days ago. On this registry it ranks #109 of 130 tracked projects in Orchestration & Scheduling, with 5 head-to-head comparisons available. It gained 19 stars over the last 30 tracked days.

What is dbos-transact-golang?

DBOS Transact for Go is an MIT-licensed Go library that adds durable, Postgres-backed workflow orchestration to ordinary Go programs, aimed at developers who need reliable failure recovery without operating a separate orchestrator or task queue.

What it is

DBOS Transact is a lightweight durable workflow orchestration framework that runs on top of Postgres. It lives in the Go ecosystem as an importable module, github.com/dbos-inc/dbos-transact-golang, and it works by checkpointing program state into a Postgres system database rather than by shipping a separate orchestration service. Developers register ordinary Go functions as workflows or run them as steps, so durability is added to existing code with a handful of calls instead of a rewrite around a new runtime.

The concrete problem it solves is recovery from mid-operation failure. A payments service that must process transactions even when servers crash halfway through, or a long-running data pipeline that needs to resume from its last checkpoint rather than restart from the beginning, would otherwise require hand-written state management and recovery logic. DBOS replaces the self-managed orchestrator or external task queue that teams typically reach for in that situation: the checkpointing, resume behaviour, and queueing live in Postgres, which the application already runs.

Key capabilities

  • Durable workflows registered with dbos.RegisterWorkflow, whose state is checkpointed in Postgres so that all workflows automatically resume from the last completed step after a restart.
  • Individual functions run inside a workflow via dbos.RunAsStep, keeping ordinary Go functions as the unit of work.
  • Durable queues that run tasks in the background by enqueueing a workflow.
  • Postgres-backed primitives beyond workflows, including durable queues, notifications, scheduling, event processing, and programmatic workflow management.
  • Context and configuration through dbos.NewContext with dbos.Config{DatabaseURL, AppName}, pointing at the system database via the DBOS_SYSTEM_DATABASE_URL environment variable.
  • A lifecycle built from dbos.Launch and dbos.Shutdown(ctx, 2 * time.Second), with dbos.RunWorkflow returning a handle whose handle.GetResult() yields the workflow result.

Who uses it and how

  • Teams building payments services that must reliably process transactions even if servers crash mid-operation.
  • Data engineering groups running long-running pipelines that should resume from checkpoints instead of restarting when interrupted.
  • Builders of AI agents and other applications that sit on top of unreliable or non-deterministic APIs.
  • Application teams orchestrating business processes that must seamlessly recover from any failure.
  • Backend developers moving background work off an external queue system and onto durable, Postgres-backed queues.

Getting started

Add the Go module github.com/dbos-inc/dbos-transact-golang, import its dbos package, point DBOS_SYSTEM_DATABASE_URL at a Postgres database, then call dbos.NewContext, register workflows, and launch with dbos.Launch. Documentation and examples are hosted at docs.dbos.dev and docs.dbos.dev/examples, with the homepage at dbos.dev.

How it compares

The supplied facts name no other workflow engine or orchestration product, so on this registry DBOS Transact stands alone in the Infrastructure & Operations / Orchestration & Scheduling category. Its stated alternative is the pair of approaches teams otherwise assemble themselves, a self-managed workflow orchestrator or a separate task queue system, both of which it replaces with functionality inside the Go process and its Postgres database.

When to use it — and when not to

A self-hoster must run and operate Postgres, because the system database is the durability substrate; there is no queue broker or storage service to add, but there is a database to keep available. It is a poor fit for non-Go stacks, and a poor fit for anyone who cannot put a Postgres instance behind the application. The project is still modest in adoption at 833 stars and 73 forks with 10 open issues, and the supplied README excerpt documents durable workflows in depth while its queues, notifications, and scheduling sections are only introduced, so those primitives warrant reading the full documentation before depending on them.

project readme (upstream, from github) — read inline

Go Reference Go Report Card GitHub release (latest SemVer) Join Discord License: MIT GitHub Stars

DBOS Transact: Lightweight Durable Workflow Orchestration with Postgres

Documentation   •   Examples   •   Github

What is DBOS?

DBOS provides lightweight durable workflow orchestration 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.

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.

Features

💾 Durable Workflows

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.

You add durable workflows to your existing Golang program by registering ordinary functions as workflows or running them as steps:

package main

import (
    "context"
    "fmt"
    "os"
    "time"

    "github.com/dbos-inc/dbos-transact-golang/dbos"
)

func workflow(dbosCtx dbos.Context, _ string) (string, error) {
    _, err := dbos.RunAsStep(dbosCtx, stepOne)
    if err != nil {
        return "", err
    }
    return dbos.RunAsStep(dbosCtx, stepTwo)
}

func stepOne(ctx context.Context) (string, error) {
    fmt.Println("Step one completed!")
    return "Step 1 completed", nil
}

func stepTwo(ctx context.Context) (string, error) {
    fmt.Println("Step two completed!")
    return "Step 2 completed - Workflow finished successfully", nil
}

func main() {
    // Initialize a DBOS context
    ctx, err := dbos.NewContext(context.Background(), dbos.Config{
        DatabaseURL: os.Getenv("DBOS_SYSTEM_DATABASE_URL"),
        AppName:     "myapp",
    })
    if err != nil {
        panic(err)
    }

    // Register a workflow
    dbos.RegisterWorkflow(ctx, workflow)

    // Launch DBOS
    err = dbos.Launch(ctx)
    if err != nil {
        panic(err)
    }
    defer dbos.Shutdown(ctx, 2 * time.Second)

    // Run a durable workflow and get its result
    handle, err := dbos.RunWorkflow(ctx, workflow, "")
    if err != nil {
        panic(err)
    }
    res, err := handle.GetResult()
    if err != nil {
        panic(err)
    }
    fmt.Println("Workflow result:", res)
}

Workflows are particularly useful for

  • Orchestrating business processes so they seamlessly recover from any failure.
  • Building observable and fault-tolerant data pipelines.
  • Operating an AI agent, or any application that relies on unreliable or non-deterministic APIs.
📒 Durable Queues

DBOS queues help you durably run tasks in the background. When you enqueue a workflow, one of your processes will pick it up for execution. DBOS manages the execution of your tasks: it guarantees that tasks complete, and that their callers get their results without needing to resubmit them, even if your application is interrupted.

Queues also provide flow control, so you can limit the concurrency of your tasks on a per-queue or per-process basis. You can also set timeouts for tasks, rate limit how often queued tasks are executed, deduplicate tasks, or prioritize tasks.

You can add queues to your workflows in just a couple lines of code. They don't require a separate queueing service or message broker—just Postgres.

package main

import (
    "context"
    "fmt"
    "os"
    "time"

    "github.com/dbos-inc/dbos-transact-golang/dbos"
)

func task(ctx dbos.Context, i int) (int, error) {
    dbos.Sleep(ctx, 5*time.Second)
    fmt.Printf("Task %d completed\n", i)
    return i, nil
}

func main() {
    // Initialize a DBOS context
    ctx, err := dbos.NewContext(context.Background(), dbos.Config{
        DatabaseURL: os.Getenv("DBOS_SYSTEM_DATABASE_URL"),
        AppName:     "myapp",
    })
    if err != nil {
        panic(err)
    }

    // Register the workflow and a durable queue
    dbos.RegisterWorkflow(ctx, task)
    queue, err := dbos.RegisterQueue(ctx, "queue")
    if err != nil {
        panic(err)
    }

    // Launch DBOS
    err = dbos.Launch(ctx)
    if err != nil {
        panic(err)
    }
    defer dbos.Shutdown(ctx, 2 * time.Second)

    // Enqueue tasks and gather results
    fmt.Println("Enqueuing workflows")
    handles := make([]dbos.WorkflowHandle[int], 10)
    for i := range 10 {
        handle, err := dbos.RunWorkflow(ctx, task, i, dbos.WithQueue(queue))
        if err != nil {
            panic(fmt.Sprintf("failed to enqueue step %d: %v", i, err))
        }
        handles[i] = handle
    }
    results := make([]int, 10)
    for i, handle := range handles {
        result, err := handle.GetResult()
        if err != nil {
            panic(fmt.Sprintf("failed to get result for step %d: %v", i, err))
        }
        results[i] = result
    }
    fmt.Printf("Successfully completed %d steps\n", len(results))
}
🎫 Exactly-Once Event Processing

Use DBOS to build reliable webhooks, event listeners, or Kafka consumers by starting a workflow exactly-once in response to an event. Acknowledge the event immediately while reliably processing it in the background.

For example:

_, err := dbos.RunWorkflow(ctx, task, i, dbos.WithWorkflowID(exactlyOnceEventID))
📅 Durable Scheduling

Schedule workflows using cron syntax, or use durable sleep to pause workflows for as long as you like (even days or weeks) before executing.

reportWorkflow := func(ctx dbos.Context, input dbos.ScheduledWorkflowInput) (any, error) {
    return fmt.Sprintf("Workflow executed at %s", input.ScheduledTime), nil
}
dbos.RegisterWorkflow(dbosCtx, reportWorkflow)

// After launching DBOS, create a database-backed schedule
err := dbos.CreateSchedule(dbosCtx, dbos.ScheduleSpec{
    ScheduleName: "report-schedule",
    Schedule:     "* * * * * *", // Every second
    Workflow:     reportWorkflow,
})

You can add a durable sleep to any workflow with a single line of code. It stores its wakeup time in Postgres so the workflow sleeps through any interruption or restart, then always resumes on schedule.

func workflow(ctx dbos.Context, duration time.Duration) (string, error) {
    dbos.Sleep(ctx, duration)
    return fmt.Sprintf("Workflow slept for %s", duration), nil
}

handle, err := dbos.RunWorkflow(dbosCtx, workflow, time.Second*5)
_, err = handle.GetResult()
📫 Durable Notifications

Pause your workflow executions until a notification is received, or emit events from your workflow to send progress updates to external clients. All notifications are stored in Postgres, so they can be sent and received with exactly-once semantics. Set durable timeouts when waiting for events, so you can wait for as long as you like (even days or weeks) through interruptions or restarts, then resume once a notification arrives or the timeout is reached.

For example, build a reliable billing workflow that durably waits for a notification from a payments service, processing it exactly-once:

func sendWorkflow(ctx dbos.Context, message string) (string, error) {
    err := dbos.Send(ctx, "receiverID", message, "topic")
    return "sent", err
}

func receiveWorkflow(ctx dbos.Context, topic string) (string, error) {
    return dbos.Recv[string](ctx, topic, 48 * time.Hour)
}

// Start a receiver in the background
recvHandle, err := dbos.RunWorkflow(dbosCtx, receiveWorkflow, "topic", dbos.WithWorkflowID("receiverID"))

// Send a message
sendHandle, err := dbos.RunWorkflow(dbosCtx, sendWorkflow, "hola!")
_, err = sendHandle.GetResult()

// Eventually get the response
recvResult, err := recvHandle.GetResult()

Getting Started

To get started, follow the quickstart to install this open-source library and connect it to a Postgres database. Then, check out the programming guide to learn how to build with durable workflows and queues.

Documentation

https://docs.dbos.dev

Examples

https://docs.dbos.dev/examples

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 this 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.

⭐️ Like this project?

Star it on GitHub GitHub Stars

Frequently asked questions

Is dbos-transact-golang free to use?

dbos-transact-golang is open source under the MIT licence. There is no licence fee and no seat count — you can self-host it or, where the project offers one, pay a vendor for a managed version instead.

What does dbos-transact-golang do?

Database-Backed Durable Golang Workflows

What is dbos-transact-golang written in?

dbos-transact-golang is primarily written in Go. Its source is publicly available at https://github.com/dbos-inc/dbos-transact-golang, and it has 863 GitHub stars.