DBOS Transact for TypeScript: Durable Workflows in Postgres
Database-Backed Durable TypeScript Workflows
At a glance
- What is it?
- DBOS Transact is a TypeScript library for durable workflows, queues, and event processing backed by Postgres. It suits services that need recovery after process failures without operating a separate workflow orchestrator.
- Who is it for?
- DBOS Transact fits teams that use TypeScript and Postgres and need recoverable business processes, durable queues, or event processing without adding a separate orchestration service. It is a poor fit for applications that cannot depend on Postgres or teams unwilling to model important work as durable workflows and steps.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Why DBOS Transact Exists
DBOS Transact addresses applications that must keep working after a server crash, process restart, or failure during a long-running operation. The README gives a payments service that must process transactions reliably and a data pipeline that needs to resume from checkpoints instead of starting over. Those are different from ordinary background jobs. The application needs both execution and enough persisted state to determine what already completed.
The library is aimed at TypeScript developers building services that can tolerate unreliable APIs or need coordinated business processes. The repository description names durable workflows, orchestration, queues, scheduling, agentic workflows, and PostgreSQL as core concerns. The package metadata describes DBOS Transact as a workflow engine and task manager for durable execution, long-running work, parallel processing, and agentic workflows.
DBOS Transact uses Postgres as the durable system of record. The README states that workflow executions are stored as rows in a Postgres table, while durable queues, scheduling, notifications, and other reliability primitives are also database-backed. This removes the need to configure a separate workflow orchestrator, task queue service, or message broker. The trade-off is an application dependency on Postgres for both application behavior and recovery metadata.
This is a narrower design than adopting a general-purpose microservice orchestration platform. Developers gain workflow recovery through annotations and DBOS calls, but they must accept Postgres as part of the runtime model. For a system that already standardizes on TypeScript and Postgres, that can reduce the number of infrastructure components involved. For a stateless service with a different database strategy, it can be an undesirable constraint.
Workflow Registration and Step Recovery
DBOS workflows are ordinary TypeScript functions registered with DBOS. Important operations are wrapped as steps through `DBOS.runStep`. The README states that workflow state is checkpointed in Postgres and that, after a failure, workflows resume from the last completed step when the program restarts.
The visible programming model is direct. A workflow calls each step with `await`, while registration supplies the durable execution boundary. In the example, `workflowFunction` calls `stepOne` and `stepTwo`; `DBOS.registerWorkflow(workflowFunction)` creates the workflow definition. The functions themselves do not show explicit persistence calls. That is the central design choice. Developers identify durable units through the DBOS API rather than writing a separate state machine or recovery protocol.
This mechanism is useful for payment processing, pipelines, and applications calling external APIs, but recovery depends on correct step boundaries. A step that fails after an external service accepts a request can create ambiguity when DBOS retries the operation. The README does not document automatic deduplication for arbitrary side effects, so applications may still need provider-supported idempotency keys or another retry strategy. The workflow tutorial should be reviewed for its guidance on external operations.
A workflow should also avoid placing unrelated work inside a single step. A broad step reduces the amount of work DBOS can safely repeat, while a narrow step records more granular progress. The README promotes checkpointed recovery but does not quantify overhead per step. Teams with high-volume, short-lived tasks should compare that persistence cost with the recovery benefit before standardizing DBOS for every function.
Postgres Queues and Background Execution
DBOS queues provide durable background execution without a separate queueing service. A workflow enqueues another registered workflow with `DBOS.startWorkflow(taskWorkflow, { queueName })(task)`, then waits for a handle and retrieves the result with `getResult()`. The README states that a DBOS process picks up queued tasks, that callers receive their results even after interruption, and that submission does not need to be repeated.
Queue behavior includes concurrency limits per queue or per process, timeouts, rate limits, deduplication, and prioritization. These controls are database-backed rather than implemented through an external broker. The workflow can enqueue several tasks in a loop and collect their results after the tasks finish, which makes fan-out operations explicit in application code.
The README includes an important startup detail: queue configuration is stored in Postgres, so the queue is registered after launch. The example calls `DBOS.launch()` and then `DBOS.registerQueue(queueName)`. Queue setup is therefore part of application startup rather than merely a declaration beside the workflow definition.
This model is attractive when a team wants background work without another service to deploy and monitor. It also means that queue operation depends on Postgres connectivity and the schema managed by DBOS. The README does not document queue retention, completed-task cleanup, regional failover, or behavior during prolonged Postgres outages. Those boundaries matter when the queue becomes a central part of production processing.
Listing, Forking, and Recovering Executions
Workflow state is not limited to an in-process runtime. `DBOSClient` provides programmatic management through a connection configured with `systemDatabaseUrl`. The documented client can list workflows by status and time range, list workflow steps, and fork a workflow from a specific step. The README example searches for `ERROR` workflows from `2025-04-22T03:00:00Z` to `2025-04-22T05:00:00Z`, then inspects step errors before calling `forkWorkflow(workflow.workflowID, 2)`.
This changes the operational model for failures that affect many executions. A script can identify affected workflow IDs, examine recorded steps, and start recovery from a selected point rather than manually editing application state. The README also describes batch pause or resume and restarting failed workflows from a step as workflow management operations.
The feature is relevant when a dependency outage has caused a repeatable failure in the same step. However, the example uses `ServiceOutage`, which is application code rather than a DBOS-provided error type. The README does not explain the exact serialization of arbitrary error objects or the safeguards around forking a workflow with external side effects. Those details need confirmation before `forkWorkflow` becomes an incident procedure.
Forking should also be treated as an application decision rather than an automatic retry. A prior step may have produced an external effect that cannot be erased. The documented API makes targeted recovery possible, but the correct step number depends on the recorded execution and the semantics of the application's operations.
Installing Node.js 20 and Registering the First Workflow
The repository directs new users to the DBOS quickstart for installation and the Postgres connection. The package metadata identifies the published package as `@dbos-inc/dbos-sdk` and requires Node.js `>=20`. The README does not provide a complete local installation command, so this article does not invent a package-manager command.
The first concrete code change is registering a workflow with steps. This example comes directly from the README. It logs completion of each step and then registers the function as a durable workflow:
async function stepOne() {
DBOS.logger.info('Step one completed!');
}
async function stepTwo() {
DBOS.logger.info('Step two completed!');
}
async function workflowFunction() {
await DBOS.runStep(stepOne);
await DBOS.runStep(stepTwo);
}
const workflow = DBOS.registerWorkflow(workflowFunction);The expected log entries are `Step one completed!` and `Step two completed!` when the functions execute. The example establishes registration and step ordering, but it does not show `DBOS.launch()` or the Postgres connection. The quickstart at `https://docs.dbos.dev/quickstart` is therefore the correct place to complete those parts of a first run.
Node.js 20 is a hard package constraint in `package.json`. Applications on an older release should resolve that prerequisite before evaluating the rest of the workflow model.
Creating a Durable Postgres Queue
A first background task requires both a registered workflow and a queue registered after launch. The README uses the following task shape and queue flow:
import { DBOS } from '@dbos-inc/dbos-sdk';
const queueName = 'example_queue';
async function taskFunction(task) {
// ...
}
const taskWorkflow = DBOS.registerWorkflow(taskFunction, { name: 'taskWorkflow' });
async function queueFunction(tasks) {
const handles = [];
for (const task of tasks) {
handles.push(await DBOS.startWorkflow(taskWorkflow, { queueName })(task));
}
const results = [];
for (const h of handles) {
results.push(await h.getResult());
}
return results;
}
const queueWorkflow = DBOS.registerWorkflow(queueFunction, { name: 'queueWorkflow' });The example submits each task and collects results after submission. It does not specify a queue concurrency limit, timeout, rate, deduplication key, or priority. Those controls are available according to the README, but their exact configuration syntax must come from the queue tutorial.
Queue configuration is stored in Postgres and must be registered after launch:
await DBOS.launch();
await DBOS.registerQueue(queueName);A successful first use should register `taskWorkflow`, submit one or more tasks through `queueWorkflow`, and return each handle's result. If `queueName` is registered before `DBOS.launch()`, the reader would be departing from the startup order shown in the README.
Event Processing Boundaries and Operational Cost
The README identifies exactly-once event processing as a DBOS capability for webhooks, event listeners, and Kafka consumers. It describes starting a workflow exactly once in response to an event and acknowledging the event, although the visible README section does not include the complete implementation details. The repository topics also include event receiver support, and `package.json` exposes an `eventreceiver` package export.
That capability is relevant to systems where an incoming event must trigger durable work without leaving an untracked operation after acknowledgement. Still, the README does not show configuration for Kafka, webhook acknowledgement, receiver startup, or event deduplication. Developers need the linked documentation to determine which sources are supported and how the acknowledgement boundary works.
Maintenance is recent by repository records. The project is not archived, its last push was on 2026-10-14, and the release list includes v5.2 on 2026-09-29, v5.1 on 2026-09-24, and v5.0 on 2026-09-16. These records show current release work, but they do not provide a compatibility policy for persisted workflows. The repository contains tests, chaos tests, schemas, workspaces, and CI configuration, but the README and package metadata do not provide coverage figures.
The package is licensed under MIT. The `LICENSE` file should be consulted for its exact terms. Upgrade cost includes reviewing DBOS API changes, Postgres schema changes, queue behavior, and the ability of deployed code to resume workflow executions created by an earlier release. Stateless deployment practices alone are insufficient when persisted workflow state must survive application updates.
Editorial conclusion
DBOS Transact fits teams that use TypeScript and Postgres and need recoverable business processes, durable queues, or event processing without adding a separate orchestration service. It is a poor fit for applications that cannot depend on Postgres or teams unwilling to model important work as durable workflows and steps. Verify first that Node.js 20 or later is available, the application can use Postgres for system state, and the documented APIs match the intended recovery behavior.
Frequently asked questions
What is DBOS Transact used for?
DBOS Transact provides durable TypeScript workflows backed by Postgres. The README identifies payments, long-running data pipelines, and applications that call unreliable or non-deterministic APIs as suitable use cases.
Does DBOS Transact require a separate workflow orchestration service?
The README states that no separate workflow orchestrator, task queue service, or message broker is required by the design. DBOS stores workflow state and queue configuration in Postgres, so the application still needs a Postgres database.
What does a DBOS Transact workflow do after a failure?
According to the README, a workflow resumes from its last completed step when the program restarts after a failure. Durable steps are registered through calls such as `DBOS.runStep`.
How are DBOS Transact queues configured?
The README example calls `DBOS.launch()` and then `DBOS.registerQueue(queueName)`. It states that queue configuration is stored in Postgres and should be registered after launch.
Can failed DBOS Transact workflows be restarted from a specific step?
Yes. The documented `DBOSClient` example lists workflow steps and calls `forkWorkflow(workflow.workflowID, 2)` to restart a selected execution from step 2.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/dbos-inc-dbos-transact-ts)Was this useful?