Guide · TypeScript and Node.js
System comparisons
Restate, DBOS, RivetKit, Graphile Worker, and Solid Objects compared on real Node.js tasks, with tested examples and primary sources.
This guide compares coordination models so an application can choose the smallest mechanism that meets its requirements. It does not rank the projects.
Comparison pages
Each page compares Solid Objects with one system on one real task. Each page says when the other system is the better choice. The Solid Objects actor and runtime code on each page runs in the test suite.
| Page | The task |
|---|---|
| Restate virtual objects and Solid Objects | AI agent sessions |
| DBOS Transact and Solid Objects | Shopping cart checkout |
| RivetKit actors and Solid Objects | Chat rooms |
| Graphile Worker named queues and Solid Objects | Chat rooms |
Coordination models
Solid Objects is a virtual actor library; the virtual actor guide defines the term. Facts about other projects were checked on October 7, 2026.
| Approach | State and serialization unit | Deployment and durable substrate | Separate service | Replay versus state | Realtime and edge placement | Cross-identity transaction | Data access |
|---|---|---|---|---|---|---|---|
| SQL transaction or row lock | Rows selected by one transaction | Application process and SQL database | No | The application retries a failed transaction | Application-owned | Yes, for rows in the same database transaction | Ordinary application tables and SQL tools |
| Traditional job queue | A job, queue, or configured grouping key | Workers plus broker or queue database | Usually | The job is retried; mutable entity state remains application-owned | Application-owned | Not supplied by the queue | Queue administration plus application data stores |
| Solid Objects | Actor class and application-defined ID | Node processes plus existing SQLite, PostgreSQL, or MySQL | No; Redis wake-up is optional | The operation retries against durable actor state | Committed projections; application-owned transport; no edge placement | No | Relational tables, typed administration, CLI, and dashboard |
| Cloudflare Durable Objects | Object class and globally unique ID | Cloudflare Workers plus per-object managed storage | Cloudflare platform | Object activation with durable state, not workflow-step replay | WebSockets and Cloudflare-selected object location | Storage transactions are scoped to one object | Object storage APIs and platform tooling |
| celld | Object class and object name | celld nodes plus one object-storage bucket; each object is its own SQLite database | Yes, the celld daemon on every node | The new owner restores the object's SQLite database from the bucket and resumes | Cloudflare Workers APIs; an object runs on one node of your fleet, not at an edge location | No | Per-object SQLite through the Workers storage APIs, plus the bucket |
| Rivet Actors | Addressable actor | Rivet control plane or managed compute with actor state, KV, or per-actor SQLite | Rivet control plane | Actor persistence and lifecycle; workflows add recorded steps | Actor events and deployment-dependent placement | No general transaction across actors | Actor APIs and selected persistence model |
| DBOS | Workflow ID and checkpointed steps | Application processes plus PostgreSQL system database | No orchestration server for the library; Conductor is recommended for distributed recovery | Deterministic workflow replay skips checkpointed steps | Workflow events; application placement | PostgreSQL transactions remain separate from workflow identity | PostgreSQL system database, client, CLI, and optional Conductor |
| Dapr actors | Actor type and ID, one turn at a time | Application services plus Dapr sidecars and a transactional actor state store | Yes: the Dapr sidecar plus the placement and Scheduler services | Actor state persists in the state store; actors do not replay workflow steps | Sidecar-routed actor placement; no edge placement | No transaction across actors | Dapr actor APIs and the configured state store |
| Restate | Service handler or keyed virtual object | Application services plus Restate's durable log and state store | Yes | Durable execution journals handler progress and object state | Service protocol and Restate deployment | No shared SQL transaction across object keys | Restate APIs, state tools, snapshots, and backups |
| Temporal | Workflow execution ID | Worker processes plus a Temporal Service, self-hosted or Temporal Cloud | Yes, the Temporal Service | Deterministic workflow code replays its event history | Workflow signals and queries; application placement | No shared SQL transaction across workflows | Temporal SDK, CLI, and web UI |
Comparison vocabulary
Each row above differs on the same dimensions. For Solid Objects they are:
| Dimension | Solid Objects |
|---|---|
| Identity | An actor class and an application-defined ID |
| Activation | On demand, behind a fenced lease, released when idle |
| State storage | A JSON document in SQLite, PostgreSQL, or MySQL |
| Serialization | One durable mailbox for each identity |
| Delivery | At least once, in order for each identity |
| Reminders | Durable and keyed for each actor |
| Recovery | Another process claims the work after a lease expires; committed work waits in SQL |
| Deployment | A library inside the application's Node.js processes |
| Operational cost | One retained message row for each call, plus database load |
Primary references
PostgreSQL documents row-lock behavior, transaction lifetime, and deadlock handling in Explicit Locking.
BullMQ is one representative traditional queue; its worker concurrency documentation distinguishes local concurrency from multiple worker processes.
Cloudflare documents global uniqueness, per-object storage, single-threaded execution, and placement in What are Durable Objects?.
celld documents per-object SQLite databases, bucket replication, and object-storage compare-and-swap ownership in its repository and its documentation.
Rivet documents addressable actors and persistence in Actors and Persistence.
DBOS documents its PostgreSQL checkpoints, recovery, distributed processes, and optional control plane in DBOS Architecture.
Restate documents per-key write serialization in Virtual Objects and its storage requirements in the self-hosted server overview.
Dapr documents virtual actors, the actor state store, and Scheduler-backed reminders in Actors overview and Actor timers and reminders. The JavaScript SDK supports actors.
Temporal documents deterministic replay in Workflow definition and its service in What is Temporal?.
Orleans documents virtual actors, turn-based scheduling, and reminders in its overview, Request scheduling, and Timers and reminders.
Node.js documents CPU-bound parallelism in Worker threads.
External systems evolve. Recheck these primary sources before relying on one row as a procurement or architecture decision.
Generated from docs/comparisons.md in
cardmagic/solid-objects-js, v1.0.2,
commit 0a26ebb. For Ruby on Rails, read
Virtual actors in Ruby on Rails.