# Golem Configure Durability Scala

> Choosing between durable and ephemeral agents in a Scala Golem project. Use when the user asks about agent durability modes, making an agent stateless, or configuring agent persistence.

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

---


# Configuring Agent Durability (Scala)

## 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:

```scala
import golem.runtime.annotations.{agentDefinition, agentImplementation}
import golem.BaseAgent

import scala.concurrent.Future

@agentDefinition(mount = "/counters/{name}")
trait CounterAgent extends BaseAgent {
  class Id(val name: String)
  def increment(): Future[Int]
  def getCount(): Future[Int]
}

@agentImplementation()
final class CounterAgentImpl(private val name: String) extends CounterAgent {
  private var count: Int = 0

  override def increment(): Future[Int] = Future.successful {
    count += 1
    count
  }

  override def getCount(): Future[Int] = Future.successful(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**.

```scala
@agentDefinition(snapshotting = "every(10)")     // snapshot every 10 successful calls
trait CounterAgent extends BaseAgent { ... }

@agentDefinition(snapshotting = "periodic(30s)") // or at most once per interval
trait HeartbeatAgent extends BaseAgent { ... }
```

See [`golem-custom-snapshot-scala`](../golem-custom-snapshot-scala/SKILL.md) for snapshotting modes and `Snapshotted[S]` / custom binary save/load hooks.

## Ephemeral Agents

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

- State is discarded after each invocation completes
- No oplog is maintained — lower overhead
- Useful for pure functions, request handlers, or adapters

```scala
import golem.runtime.annotations.{agentDefinition, DurabilityMode}

@agentDefinition(mode = DurabilityMode.Ephemeral)
trait StatelessHandler extends BaseAgent {
  def handle(input: String): Future[String]
}
```

## 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-scala`](../golem-custom-snapshot-scala/SKILL.md).

