Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@
to flush each commit before it returns. The adapter switches an existing file
to WAL on its first access, with the same retries as a transaction. WAL keeps
`-wal` and `-shm` files next to the database.
- Add `docs/compare/ai-agents.md`, durable execution for TypeScript AI agents
on PostgreSQL. One table compares Restate, DBOS Transact, Temporal, and
Solid Objects: where the state lives, what a crash repeats, how a delayed
follow-up works, and what you run. The page embeds the tested agent session
example. `docs/comparisons.md` lists it.
- The Restate page now answers how delayed messages and timers work. The DBOS
page answers how durable sleep, `send`, and `recv` work. The Graphile Worker
page answers whether jobs with the same `queue_name` run serially, and
describes `job_key` and `run_at`. Each answer quotes the official
documentation and gives the date that it was checked.
- The short answer in `docs/virtual-actors.md` no longer states that version
1.0 makes no claim of measured scale. It links `docs/versioning.md`, the one
page that states the limits of version 1.0. Version 1.0.5 missed this
Expand Down
252 changes: 252 additions & 0 deletions docs/compare/ai-agents.md

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions docs/compare/dbos.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@ The DBOS facts come from the [DBOS documentation](https://docs.dbos.dev) and the

Two DBOS pages differ on more than one process. The FAQ says "Conductor is required for correct workflow recovery in applications that use more than one process". The recovery page describes recovery without Conductor: each process has an executor ID, and a restarted process recovers its own pending workflows.

## How do durable sleep, send, and recv work in DBOS?

`DBOS.sleep` is a durable sleep inside a workflow. It takes milliseconds. DBOS "saves the wakeup time in the database so that even if the workflow is interrupted and restarted multiple times while sleeping, it still wakes up on schedule" ([DBOS workflow tutorial](https://docs.dbos.dev/typescript/tutorials/workflow-tutorial), checked October 18, 2026). `DBOS.send` sends a message to a workflow, and `DBOS.recv` in that workflow waits for it. "Messages are dequeued first-in, first-out from a queue associated with the topic" ([DBOS methods reference](https://docs.dbos.dev/typescript/reference/methods)).

- `DBOS.recv` waits up to `timeoutSeconds` and then returns `null`. "The default timeout is 60 seconds" ([DBOS workflow communication](https://docs.dbos.dev/typescript/tutorials/workflow-communication)).
- "If you're sending a message from a workflow, DBOS guarantees exactly-once delivery" ([DBOS workflow communication](https://docs.dbos.dev/typescript/tutorials/workflow-communication)).
- With `delaySeconds` on enqueue, the workflow "is initially placed in `DELAYED` status and transitions to `ENQUEUED` after the delay expires" ([DBOS methods reference](https://docs.dbos.dev/typescript/reference/methods)).
- A partitioned queue with `partitionConcurrency: 1` runs one workflow at a time for each `queuePartitionKey`.
- In Solid Objects, a message to the actor replaces `send` and `recv`, and a reminder (`this.schedule({ at, key }).operation(input)`) replaces a durable sleep. Solid Objects has no durable wait inside a turn. The turn that stores the reminder ends, so other messages for the same cart run before the reminder runs.

## Choose DBOS when

- The work is a sequence of steps, and a completed step must not run again after a crash.
Expand Down Expand Up @@ -381,6 +391,8 @@ Checked October 15, 2026:
- [DBOS upgrading workflows](https://docs.dbos.dev/typescript/tutorials/upgrading-workflows)
- [Migrating from Temporal to DBOS](https://docs.dbos.dev/explanations/migrating-from-temporal)
- [DBOS pricing](https://www.dbos.dev/dbos-pricing)
- [DBOS methods reference](https://docs.dbos.dev/typescript/reference/methods) (checked October 18, 2026)
- [DBOS workflow communication](https://docs.dbos.dev/typescript/tutorials/workflow-communication) (checked October 18, 2026)

## More information

Expand Down
11 changes: 11 additions & 0 deletions docs/compare/graphile-worker.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ Solid Objects is an independent project. It is not affiliated with Graphile.

The Graphile Worker facts come from the [Graphile Worker documentation](https://worker.graphile.org/docs) and its [source code](https://github.com/graphile/worker) (checked October 15, 2026).

## Do jobs with the same `queue_name` run serially?

Yes. Jobs in the same named queue run one at a time. The SQL function `graphile_worker.add_job` takes `queue_name`, and the JavaScript `addJob` takes `queueName`: "if you want certain tasks to run one at a time, add them to the same named queue" ([Graphile Worker `add_job`](https://worker.graphile.org/docs/sql-add-job), checked October 18, 2026).

- The `TaskSpec` type describes `queueName` as "The queue to run this task under (only specify if you want jobs in this queue to run serially)" ([`addJob`](https://worker.graphile.org/docs/library/add-job)).
- Serial is not the same as ordered after a failure. See the "Order after a failure" row above.
- `job_key` (`jobKey` in JavaScript) is a "unique identifier for the job, used to replace, update or remove it later if needed" ([`add_job`](https://worker.graphile.org/docs/sql-add-job)). `job_key_mode` (`jobKeyMode` in JavaScript) is `replace` (the default), `preserve_run_at`, or `unsafe_dedupe` ([job keys](https://worker.graphile.org/docs/job-key)).
- `run_at` (`runAt` in JavaScript) is "a timestamp after which to run the job; defaults to now".
- In Solid Objects, the actor ID replaces `queue_name`, and `this.schedule({ at, key }).operation(input)` replaces `run_at` with a `job_key`.

## Choose Graphile Worker when

- The work is background jobs, such as emails, webhooks, or reports.
Expand Down Expand Up @@ -277,6 +287,7 @@ Checked October 15, 2026:

- [Graphile Worker introduction](https://worker.graphile.org/docs)
- [Graphile Worker `addJob`](https://worker.graphile.org/docs/library/add-job)
- [Graphile Worker `add_job` in SQL](https://worker.graphile.org/docs/sql-add-job) (checked October 18, 2026)
- [Graphile Worker job keys](https://worker.graphile.org/docs/job-key)
- [Graphile Worker error handling](https://worker.graphile.org/docs/error-handling)
- [Graphile Worker exponential backoff](https://worker.graphile.org/docs/exponential-backoff)
Expand Down
13 changes: 12 additions & 1 deletion docs/compare/restate.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ Solid Objects is an independent project. It is not affiliated with Restate.

The Restate facts come from the [Restate documentation](https://docs.restate.dev) and the [Restate server licence](https://github.com/restatedev/restate/blob/main/LICENSE) (checked October 15, 2026).

## How do delayed messages and timers work in Restate?

Restate names two ways to schedule work later in TypeScript. You can send a delayed message ([`restate.rpc.sendOpts({ delay })`](https://docs.restate.dev/develop/ts/service-communication)), or you can sleep (`ctx.sleep`) and then send a message. Restate recommends delayed messages, because "Other requests to the same Virtual Object can be processed during the delay period" ([Restate scheduling and timers](https://docs.restate.dev/develop/ts/durable-timers), checked October 18, 2026).

- Restate "tracks and manages timers, ensuring they survive failures and restarts".
- "If you sleep in an exclusive handler in a Virtual Object, all other calls to this object will be queued."
- The SDK pages, the TypeScript pages included, call this a delayed message. Some operations pages, such as versioning and managing invocations, call it a delayed call.
- In Solid Objects, `this.schedule({ at, key }).operation(input)` stores a reminder in the same SQL transaction as the turn. The turn ends at once, so other messages do not wait. One operation and key hold one alarm, and you can [cancel a reminder](../api.md#cancelling-a-reminder).

## Choose Restate when

- You want a journal of each step, so that a retry resumes after the last completed step.
Expand Down Expand Up @@ -272,13 +281,15 @@ Restate reached 1.0 in June 2024. If a longer history matters more than keeping
Checked October 15, 2026:

- [Restate services and virtual objects](https://docs.restate.dev/foundations/services)
- [Restate service communication and delayed calls](https://docs.restate.dev/develop/ts/service-communication)
- [Restate service communication and delayed messages](https://docs.restate.dev/develop/ts/service-communication)
- [Restate durable steps](https://docs.restate.dev/develop/ts/durable-steps)
- [Restate durable agents](https://docs.restate.dev/ai/patterns/durable-agents)
- [Restate agent sessions](https://docs.restate.dev/ai/patterns/sessions)
- [Restate sagas](https://docs.restate.dev/guides/sagas)
- [Restate service configuration](https://docs.restate.dev/services/configuration)
- [Restate server overview](https://docs.restate.dev/server/overview)
- [Restate databases guide](https://docs.restate.dev/guides/databases)
- [Restate scheduling and timers](https://docs.restate.dev/develop/ts/durable-timers) (checked October 18, 2026)
- [Restate server licence](https://github.com/restatedev/restate/blob/main/LICENSE)

## More information
Expand Down
1 change: 1 addition & 0 deletions docs/comparisons.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ runtime code on each page runs in the test suite.
| [DBOS Transact and Solid Objects](compare/dbos.md) | Shopping cart checkout |
| [RivetKit actors and Solid Objects](compare/rivetkit.md) | Chat rooms |
| [Graphile Worker named queues and Solid Objects](compare/graphile-worker.md) | Chat rooms |
| [Durable execution for TypeScript AI agents](compare/ai-agents.md) | AI agent sessions |

## Coordination models

Expand Down
11 changes: 11 additions & 0 deletions scripts/check-documentation.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const comparisonPages = [
"docs/compare/dbos.md",
"docs/compare/rivetkit.md",
"docs/compare/graphile-worker.md",
"docs/compare/ai-agents.md",
]

for (const documentationPath of documentationPaths) {
Expand Down Expand Up @@ -151,6 +152,16 @@ const embeddedExamples = [
example: "examples/compare/agent-runtime.ts",
language: "typescript",
},
{
documentation: "docs/compare/ai-agents.md",
example: "examples/compare/agent-session.ts",
language: "typescript",
},
{
documentation: "docs/compare/ai-agents.md",
example: "examples/compare/agent-runtime.ts",
language: "typescript",
},
{
documentation: "docs/compare/dbos.md",
example: "examples/compare/shopping-cart.ts",
Expand Down
Loading