Measured, not promised.
Akter against six actor and workflow systems and two plain databases, on the same machine, under the same HTTP workload. Medians of three runs. Where Akter loses, it says so.
Machine. One Daytona sandbox, 4 CPUs and 8 GiB shared by every app, database and driver.
Systems. Rivet (two save modes), workerd local, Restate, Temporal, DBOS, plain Postgres, plain Redis.
When. 2026-10-01 to 02. Three rounds, forward, reverse, forward.
Each bar is the median of three rounds; the hairline beneath it spans the lowest to the highest round. Plain Postgres and Redis are printed beside each case, not drawn, because they skip what an actor adds.
Sequential write
One caller, one key. Successful acknowledged writes per second.
One hot key, 64 callers
Every caller writes to the same identity. Successful writes per second.
* Temporal: 171 measured errors; the figure counts successful requests only.
10,000 keys, 64 callers
Writes spread across many fresh identities. Successful writes per second.
Sequential read
Committed-state read through HTTP. Median latency, lower is better.
First command to a new key
Creating an identity while the process is running. Median latency, lower is better.
* Rivet saved: 1 measured error; the figure counts successful requests only.
Wake after idle
First command after 15 s idle. Median latency, lower is better.
acknowledged IDs in the final crash and partition control
Each drill injects four failures: killing the app, killing storage, or partitioning the network. Every acknowledged ID is read back afterwards.
| Round | Drill | Acknowledged | Missing | Repeated | Unknown |
|---|---|---|---|---|---|
| clean1 | chaosApp | 52,379 | 0 | 0 | 16 |
| clean1 | chaosStorage | 49,144 | 0 | 0 | 0 |
| cleanchaos | chaosApp | 69,945 | 0 | 0 | 0 |
| cleanchaos | chaosStorage | 72,798 | 0 | 0 | 0 |
| cleanchaos | partitionApp | 70,623 | 0 | 0 | 0 |
| correctedfailure | chaosApp | 72,551 | 0 | 0 | 0 |
| correctedfailure | chaosStorage | 58,716 | 0 | 0 | 0 |
| correctedfailure | partitionApp | 61,527 | 0 | 0 | 0 |
Where we lose
- Plain Postgres and Redis were much faster. They skip actor lifecycle, receipts, events and the outbox.
- Restate roughly doubled Akter's throughput across 10,000 keys.
- DBOS's direct-SQL reads were faster than Akter's actor read path.
- Cloud and isolate advantages, like Cloudflare's replication network, are not measured here.
The fine print
- Same-host observations on one sandbox, not production SLOs.
- Systems acknowledge at different durability boundaries; the report lists each one.
- Missing or timed-out cases stay "not collected", never a pass.