From the creators of Postgres & Apache Spark -- Build reliable backends effortlessly

Cambridge, MA
Pinned Tweet
Six years ago, DBOS started as a joint research project at MIT and Stanford on applying database principles to modern applications. Today we announced a major milestone: the issuance of U.S. Patent for our database-centric durable workflow architecture. This recognizes the unique approach we’ve taken to simplify durable workflow orchestration by turning the database itself into a workflow engine, rather than hosting specialized infrastructure to do the same. We're so grateful to be building this!
3
4
30
21,435
DBOS retweeted
Be aware of Postgres SELECT DISTINCT.
1
2
5
243
DBOS retweeted
Separating workflow inputs/outputs into their own tables laid the groundwork for our batching and data locality improvements in data retention (see our recent blog post). One note: we deliberately left out foreign key references between those tables, so we can delete from each table in batches without the overhead of FK checks or cascading deletes. Sometimes what you don't see in the schema can matter for performance.
Optimization story time! So in DBOS, every workflow is represented by a row in a Postgres workflow status table, which stores the workflow’s status. I was trying to figure out where to store the workflow’s inputs and outputs. The natural thing to do, and the thing we did originally, was to make them columns of the workflow status table. That way, they’re updated with the rest of the status. The issue is that workflow inputs and outputs can be large. This is tricky because Postgres does multi-version concurrency control (MVCC), meaning that every time you update any value in a row, Postgres rewrites the entire row. So storing inputs and outputs directly in the workflow status table is dangerous, because they could get rewritten many times by unrelated status changes. But this isn’t the end of the story, because Postgres has another feature specifically to manage large columns: aptly named “the oversized-attribute storage technique (TOAST)”. What this does is store large column values in their own separate “TOAST tables” both to give them more space and to make sure they aren’t rewritten every time the main row is updated. So storing inputs and outputs in the workflow status table is safe, because Postgres TOASTs them and they aren’t rewritten. But this also isn’t the end of the story, because we need to be able to efficiently delete workflows after they’re done processing. And if workflow inputs and outputs are TOASTed, they’ll be stored in random locations on disk far from their parent workflow status row. So that means when we do a batch delete of workflows, we have to seek all their TOASTed inputs and outputs, which causes cache thrashing and terrible performance. So storing inputs and outputs directly in the workflow status table is dangerous, because it makes deleting workflows too expensive. So what we finally ended up doing is normalizing the main workflow status table and pulling workflow inputs and outputs into their own tables. When deleting workflows, we delete from each table separately, so all data is deleted in insertion order, giving us good cache locality and performance. What’s the takeaway from all this? At enough scale, all abstractions are leaky! None of these details (MVCC, TOAST, cache locality) are in the SQL spec, but you need to understand them to make a Postgres-backed system fast. Ultimately, making any system work well requires deeply understanding how it interacts with everything below it.
1
3
15
1,392
Optimization story time! So in DBOS, every workflow is represented by a row in a Postgres workflow status table, which stores the workflow’s status. I was trying to figure out where to store the workflow’s inputs and outputs. The natural thing to do, and the thing we did originally, was to make them columns of the workflow status table. That way, they’re updated with the rest of the status. The issue is that workflow inputs and outputs can be large. This is tricky because Postgres does multi-version concurrency control (MVCC), meaning that every time you update any value in a row, Postgres rewrites the entire row. So storing inputs and outputs directly in the workflow status table is dangerous, because they could get rewritten many times by unrelated status changes. But this isn’t the end of the story, because Postgres has another feature specifically to manage large columns: aptly named “the oversized-attribute storage technique (TOAST)”. What this does is store large column values in their own separate “TOAST tables” both to give them more space and to make sure they aren’t rewritten every time the main row is updated. So storing inputs and outputs in the workflow status table is safe, because Postgres TOASTs them and they aren’t rewritten. But this also isn’t the end of the story, because we need to be able to efficiently delete workflows after they’re done processing. And if workflow inputs and outputs are TOASTed, they’ll be stored in random locations on disk far from their parent workflow status row. So that means when we do a batch delete of workflows, we have to seek all their TOASTed inputs and outputs, which causes cache thrashing and terrible performance. So storing inputs and outputs directly in the workflow status table is dangerous, because it makes deleting workflows too expensive. So what we finally ended up doing is normalizing the main workflow status table and pulling workflow inputs and outputs into their own tables. When deleting workflows, we delete from each table separately, so all data is deleted in insertion order, giving us good cache locality and performance. What’s the takeaway from all this? At enough scale, all abstractions are leaky! None of these details (MVCC, TOAST, cache locality) are in the SQL spec, but you need to understand them to make a Postgres-backed system fast. Ultimately, making any system work well requires deeply understanding how it interacts with everything below it.
5
3
32
3,144
DBOS retweeted
I've been wrestling with durable exec for days. Trying out @DBOS_Inc and things just click!!! Great software.
1
5
7
241
Or if you want reasonable latency, a library and Postgres
I used to think durable execution required a server and workers. Now I think it's just a library and an S3 bucket. Change my mind.
2
3
10
779
DBOS now integrates with the Vercel AI SDK! This integration makes your AI SDK agents durable, backed by your Postgres database. It checkpoints every action (model and tool call) your agents take in Postgres, so if your agent is interrupted, it automatically uses those checkpoints to recover from where it left off. This lets you build long-running agents with a human in the loop, or agents performing sensitive or critical tasks, without worrying about what happens when models or infrastructure fail. Check it out! 👇
2
4
11
1,627
DBOS retweeted
Many of the improvements here came from working with large enterprises deploying durable agents in production. It's a nice example of how open source makes the feedback loop easier and faster, so our project can get better through real world use.
DBOS now integrates with the Vercel AI SDK! This integration makes your AI SDK agents durable, backed by your Postgres database. It checkpoints every action (model and tool call) your agents take in Postgres, so if your agent is interrupted, it automatically uses those checkpoints to recover from where it left off. This lets you build long-running agents with a human in the loop, or agents performing sensitive or critical tasks, without worrying about what happens when models or infrastructure fail. Check it out! 👇
1
10
981
DBOS retweeted
Cool visualization. It's also a reminder to check where your database lives. You probably want to co-locate your servers with your DB. We once helped a user debug performance issues and figured out that their servers were in us-east, but their database was in us-west. Every database call became a cross-country trip..
Reminder that your benchmark latencies don't mean anything if I don't know precisely where the client and server are located.
4
9
746
DBOS retweeted
Batching and data locality are two powerful optimizations in systems design. They're also key to making data retention scale in DBOS. In this post, we share a few war stories from debugging our Postgres implementation and answer a question we often hear: "Why don't you just use table partitioning?"
New blog post on another Postgres scaling war story 🐘 When trying to scale 20K+ deletes/sec, ran into two tricky issues: 1. Deletes cascading through foreign keys caused cache thrashing that cut throughput by 10x. 2. After a large batch of deletes finished, index lookups could take 20+ minutes navigating a wall of dead tuples. We talk about how deletes actually work in Postgres, what went wrong, and how we fixed it. Check it out! 👇
1
3
13
1,017
New blog post on another Postgres scaling war story 🐘 When trying to scale 20K+ deletes/sec, ran into two tricky issues: 1. Deletes cascading through foreign keys caused cache thrashing that cut throughput by 10x. 2. After a large batch of deletes finished, index lookups could take 20+ minutes navigating a wall of dead tuples. We talk about how deletes actually work in Postgres, what went wrong, and how we fixed it. Check it out! 👇
6
2
14
2,543
DBOS retweeted
Simple and elegant design usually scales better too.
When you do boring shit, you tend to over engineer it When you do ambitious shit, you’re forced to keep it simple Great lessons in there
1
6
527
We just released v1.4.0 of DBOS Go This release adds: - Native support for fair partitioned queues - Payload table normalization (splitting workflow inputs and outputs into their own tables) that significantly improved performance and scalability The change is forward compatible: v1.4+ can read workflows created by v1.3, while v1.3 clients will not read payloads from v1.4+ workflows. Release notes: github.com/dbos-inc/dbos-tra…
3
9
397
DBOS retweeted
We keep pushing the performance limits of Postgres. This time we again improved performance by 10x for workflows with large inputs/outputs, mostly by reducing the MVCC bloat.
We’ve just released new major versions of DBOS Python (3.0) and TS (5.0)! The headline features are schema changes (namely, splitting workflow inputs and outputs into their own tables) that should substantially improve performance at scale, especially when workflow data volumes are large. We’re also releasing large optimizations to workflow retention policies. More on that later in future posts… As major versions, these remove some deprecated/legacy interfaces. We’ve published upgrade guides to help you migrate away from these if you’re still using them. Check out the release notes 👇
1
17
1,497
We’ve just released new major versions of DBOS Python (3.0) and TS (5.0)! The headline features are schema changes (namely, splitting workflow inputs and outputs into their own tables) that should substantially improve performance at scale, especially when workflow data volumes are large. We’re also releasing large optimizations to workflow retention policies. More on that later in future posts… As major versions, these remove some deprecated/legacy interfaces. We’ve published upgrade guides to help you migrate away from these if you’re still using them. Check out the release notes 👇
1
4
17
2,330
Want to know how we built durable execution in Rust on top of Postgres? Check out this video for a first look at DBOS Rust, where Harry walks through how it works under the hood and demos what building durable Rust applications with DBOS looks like. Recorded at the DBOS User Group Meeting on September 10, 2026. Feedback is much appreciated! piped.video/kaQnXNwjcGc
1
4
10
746
Check out this new tutorial video. Harry demonstrates the new DBOS Conductor CLI tool, dbosctl, for managing durable workflow execution. See how you can inspect and manage workflows directly from the terminal, making it easier to operate DBOS applications from local and CI/CD environments. This demo is from the DBOS User Group Meeting on September 10, 2026. piped.video/77A21Sqt5Ug
4
6
476
Are you ready for a first look at DBOS Rust? We’ll be previewing it at user group tomorrow (9/10) at 11 AM PT. Come check it out! Link below 👇
1
2
10
606
DBOS retweeted
The DBOS Transact Rust repo is now public! It's still under development. We'll share more at the monthly DBOS virtual user group meetup this Thursday.
2
6
21
1,537
Much-requested new feature: step timeouts in Python! You can now run a step with a timeout. If the step exceeds the timeout, it’s preempted and a timeout error is thrown and checkpointed. Currently, this is only available for async steps because Python provides an elegant preemption mechanism for async functions (async cancellation), but not sync functions.
1
2
9
627