# Golem Configure Durability Moonbit

> Choosing between durable and ephemeral agents in a MoonBit Golem project. Use when the user asks to change durability mode, switch between durable and ephemeral, or configure persistence behavior.

- Skill: `golemcloud/golem-configure-durability-moonbit` (Agent Skill)
- Install (CLI): `npx skillmds@latest add golemcloud/golem-configure-durability-moonbit`
- Raw SKILL.md: https://api.skillmd.com/api/skills/golemcloud/golem-configure-durability-moonbit/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: golemcloud (https://skillmd.com/u/golemcloud)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/golemcloud/golem-configure-durability-moonbit

---


# Configuring Agent Durability (MoonBit)

## Durable Agents (Default)

By default, all Golem agents are **durable**:

- State persists across invocations, failures, and restarts
- Every side effect is recorded in an **oplog** (operation log)
- On failure, the agent is transparently recovered by replaying the oplog
- No special code needed — durability is automatic

> **You cannot opt out of oplog writes for a durable agent.** The oplog is how durability works — every side effect must be recorded. If you are worried about oplog volume or replay cost (long-running agents, heartbeats, polling, recurring tasks), do *not* try to skip persistence. Use **durable with periodic snapshots** instead (see below).

A standard durable agent:

```moonbit
#derive.agent
struct CounterAgent {
  name: String
  mut count: UInt
}

fn CounterAgent::new(name: String) -> CounterAgent {
  { name, count: 0 }
}

pub fn CounterAgent::increment(self: Self) -> UInt {
  self.count = self.count + 1
  self.count
}

pub fn CounterAgent::get_count(self: Self) -> UInt {
  self.count
}
```

## Durable with Periodic Snapshots

Same durability guarantees as the default durable mode, but recovery starts from the **latest snapshot** instead of replaying the full oplog from the beginning. Use this whenever the oplog grows unboundedly — long-running agents, high-frequency state changes, **heartbeats, polling loops, recurring tasks**.

```moonbit
#derive.agent(snapshotting="every_n(10)")    // snapshot every 10 successful calls
struct CounterAgent { ... }
```

See [`golem-custom-snapshot-moonbit`](../golem-custom-snapshot-moonbit/SKILL.md) for snapshotting modes and the `Snapshottable` trait.

## Ephemeral Agents

Use **ephemeral** mode for stateless, per-invocation agents where persistence is not needed:

- State is discarded after each invocation completes
- No oplog replay — lower overhead (an oplog is still recorded lazily for debugging via `golem agent oplog`, but never replayed)
- Each invocation calls `new()` to create a fresh instance, executes the method, then discards the instance
- Useful for pure functions, request handlers, or adapters

```moonbit
#derive.agent("ephemeral")
struct StatelessHandler {
}

fn StatelessHandler::new() -> StatelessHandler {
  {  }
}

pub fn StatelessHandler::handle(self: Self, input: String) -> String {
  "processed: " + input
}
```

## When to Choose Which

| Use Case | Mode |
|----------|------|
| Counter, shopping cart, workflow orchestrator | **Durable** (default) |
| Stateless request processor, transformer | **Ephemeral** |
| Long-running saga or multi-step pipeline | **Durable** (default) |
| Pure computation, no side effects worth persisting | **Ephemeral** |
| Agent that calls external APIs with at-least-once semantics | **Durable** (default) |
| Long-running agent with heartbeats, polling, or recurring tasks | **Durable + periodic snapshots** |
| Any durable agent whose oplog grows so large that replay is slow | **Durable + periodic snapshots** |

When in doubt, use the default (durable). Ephemeral mode is an optimization for agents that genuinely don't need persistence. Add periodic snapshots whenever recovery time matters — see [`golem-custom-snapshot-moonbit`](../golem-custom-snapshot-moonbit/SKILL.md).

## Switching Between Modes

To make a durable agent ephemeral, change:

```moonbit
#derive.agent
struct MyAgent {
```

to:

```moonbit
#derive.agent("ephemeral")
struct MyAgent {
```

To make an ephemeral agent durable, change `#derive.agent("ephemeral")` back to `#derive.agent`.

After changing the annotation, rebuild with `golem build` to regenerate derived files. **Never edit generated files** — `golem_reexports.mbt`, `golem_agents.mbt`, and `golem_derive.mbt` are auto-generated.

