The framework for durable, stateful backends that power realtime apps, background work, and agents.
bun add @rikalabs/akter@alphaAn actor framework for TypeScript.
An actor is a container for one thing in your app: an order, a chat room, an agent session. Everything that thing needs is packed inside.
- 1An address. Order/ord_8f2c, reachable from anywhere.
- 2Commands, one at a time. Each one commits in its own transaction.
- 3State and tables. Rows in your Postgres, owned by this actor.
- 4Events and jobs. Durable, retried, and run after the commit.
- 5Live clients. Connections that stay open while it sleeps.
Define it, handle it, call it.
export const Order = Actor.make("Order", {
key: Schema.NonEmptyString,
state: Actor.state({
total: Schema.optional(Schema.Int),
chargeId: Schema.optional(Schema.String),
}),
tables: [orderLines],
events: [OrderPlaced],
jobs: { Charge: { job: Charge, onSuccess: Charged } },
api: { Place },
internal: { Charged },
})export const checkout = Effect.gen(function* () {
const order = yield* Order.get("o-1")
return yield* order.Place({ lines: [{ sku: "mug", quantity: 2, unitPrice: 1200 }] })
})export const OrderLive = Order.toLayer({
Place: Effect.fn(function* ({ lines }) {
const turn = yield* Order.Turn
if (turn.state.total !== undefined) return yield* AlreadyPlaced.make({})
const total = lines.reduce((sum, line) => sum + line.quantity * line.unitPrice, 0)
yield* turn.rows(orderLines).insert(lines)
yield* turn.emit(OrderPlaced.make({ total }))
yield* turn.enqueue(Charge.make({ amount: total }))
yield* turn.state.set({ total })
return total
}),
Charged: Effect.fn(function* ({ chargeId }) {
const turn = yield* Order.Turn
yield* turn.state.set({ chargeId })
}),
})One command, one transaction.
Committed one transaction- Actor
- Order/o-1
- Command
- Place ยท 1 line
- Result
- 2400
- Committed
- rows ยท OrderPlaced ยท state
- After commit
- Charge โ Charged
A chat room is an actor.
Rooms, documents and dashboards that keep their history and push every change to connected clients.
A billing run is an actor.
Payments, imports and billing runs that retry with backoff, run on schedules, and never quietly vanish.
An agent session is an actor.
Sessions that keep their transcript, pause for an approval, and resume after a crash or a deploy.
One hot key, 64 callers
Successful writes per second, median of three runs on the same 4-CPU sandbox.
* Temporal: 171 measured errors; the figure counts successful requests only.
Same-host observations, not production SLOs. Plain Postgres and Redis were faster, and Restate was faster across 10,000 keys. Full method in BENCHMARKS.md.
Read the benchmark report โProcess kills and network partitions, every acknowledgement checked afterwards.
Your first actor, running on your Postgres, in a few minutes.
Read the docs โ01What is an actor, exactly?
An addressable part of your app, such as one order, one room or one agent session. It handles one command at a time and owns its data, its background work and its live connections.
02Do I need Postgres?
Your data lives in Postgres, as ordinary tables you can query with plain SQL. To start, PGlite, an embedded Postgres, runs the same code with no Docker or database server; Database.postgres points it at a real server. In the alpha, run one runtime process per database.
03Can I run it inside my existing server?
Yes. Embedded, you provide Actors.layer and call actors as Effects in your own process. Served, Actors.serve exposes the same actors over HTTP, WebSocket and SSE, with an OpenAPI document and an MCP endpoint.
04What happens when a process dies mid-command?
Before the commit, nothing was written, and a retry with the same command ID places the order once. After the commit but before the reply, the retry finds the stored result and returns it without running the handler again.
05How is this different from a workflow engine?
Temporal and Restate record a function's steps so it can resume after a crash. An Akter command is a short transaction instead, and anything slow becomes a job or a workflow owned by the actor.
06Is there a hosted version?
Akter cloud, with managed runners, Postgres and an inspector for every actor, is in development and its pricing here is a placeholder. The framework is Apache-2.0 and runs wherever Bun does.