Control durability guarantees
Durable agents record host interactions in the oplog. Recovery replays completed calls from their
recorded outcomes and repairs an eligible incomplete call at its own Start. It does not rerun a
group of completed effects. Guests cannot disable recording or change the execution cursor.
Use SDK sagas for workflows that need compensation. Use retry policies for retryable host operations. A trap is permanent; return an error for a transient condition and use a retry schedule. Throwing after an HTTP response does not retry that completed request.
Remote-write safety
Golem treats remote writes as eligible for re-execution. An incomplete call can therefore be retried even when the peer might already have applied it. External exactly-once behavior requires the peer to enforce an idempotency key; a header alone is not a guarantee.
There is no guest idempotence-mode switch. Make writes duplicate-safe at the peer before relying
on retries or crash recovery. A lost response does not prove the write failed. Retry predicates
must not use is-idempotent: the host no longer supplies that property.
Custom durable operations
Custom durable operations let SDK and library authors group host effects into one logical call with a typed request and response. Completing the operation records the result; replay returns that result without evaluating the body. Leaving it unfinished does not trigger a retry. Recovery of an eligible incomplete custom call reruns its whole body, so the library must make repeated attempts safe.
Application code should normally use the high-level SDK APIs and Golem’s built-in durability instead. When writing an SDK or library, give each custom operation a stable name, a typed semantic request, and a recorded outcome. Classify it as a local or remote read or write. Use an SDK combinator to manage recording and replay rather than handling runtime resources yourself.
The examples below record a catalog revision read. The readRevision (or read_revision) adapter performs the physical read. The fixed catalog name is the request; the revision is the result. Each example calls one adapter without starting concurrent work.
TypeScript
import { durable, FunctionType } from "@golemcloud/golem-ts-sdk"
import { z } from "zod"
function catalogRevision(readRevision: (catalog: string) => string): string {
return durable({
iface: "catalog-library",
function: "read-revision",
functionType: FunctionType.readRemote,
requestSchema: z.string(),
success: z.string(),
}, "public", () => readRevision("public"))
}An adapter exception leaves the operation unfinished instead of recording an error result.
Use durable sequentially; do not overlap it with other promises or callbacks. A custom operation’s execution scope remains installed while its body waits. Unrelated guest work, including ordinary host calls, can be attributed to the wrong operation and cause incorrect replay or invocation failure. The SDK does not reliably detect this misuse.
Sequential and properly nested custom operations are supported. An asynchronous body can await host operations when no unrelated guest work runs during those waits. Complete one custom operation before starting the next; await each nested operation before continuing its parent.
Do not leave detached promises or callbacks running after the body exits, including on failure or cancellation. Stop and join outstanding work before closing the operation. Promise.all does not join surviving siblings on rejection, and joining at the end does not make concurrent custom scopes supported.
The combinators serialize recorded outcomes, including declared error results. A completed operation replays its outcome without calling the adapter. This does not make arbitrary external side effects exactly once: recovery can repeat an unfinished body, so writes still need an external idempotency key or a transaction.
Keep requests and outcomes bounded. The request, response, operation name, and observational host calls may appear in oplog inspection, logs, and metrics. Use useful schemas and names, but redact credentials and personal data.
The custom-operation restrictions do not apply to ordinary built-in durable HTTP and RPC APIs.
Nonresumable handles
A live connection is not durable state. Nonresumable handles report typed loss after reconstruction. Handle the loss by explicitly opening and initializing a new session. Do not silently resend pending traffic: loss does not prove that an earlier write never reached the peer. See WebSockets for the supported reconstruction policies.
Commit oplog
oplog-commit waits for replication before execution continues. It is a replication barrier,
not a transaction commit for external services, and it does not undo any effect.
TypeScript
import { oplogCommit } from '@golemcloud/golem-ts-sdk';
oplogCommit(3);