Snapshots are an opt-in feature for workflows with very long histories. They reduce the cost of repeatedly loading, decoding, and matching old journal events. They do not snapshot a BEAM continuation.
Workflow code still re-executes from the top on every resume. A snapshot is a compacted history prefix: each compacted step validates that the workflow is asking for the same effect at the same command identity, then returns the previously journaled result and advances the cursor by the number of raw events covered by that step.
Configuration
Snapshots are disabled by default:
config :continuum,
snapshot_threshold: :infinity,
snapshot_max_size_bytes: 1_000_000Set :snapshot_threshold to a positive integer to opt in. For example,
snapshot_threshold: 200 asks Continuum to consider taking a new snapshot after
roughly 200 additional events since the previous snapshot. :snapshot_max_size_bytes
is a safety cap for the encoded snapshot payload; oversized snapshots are
skipped and emit [:continuum, :snapshot, :skipped].
Workflows can override the app default:
defmodule MyApp.SubscriptionFlow do
use Continuum.Workflow, version: 1, snapshot_threshold: 500
endResolution order is workflow option, then runtime/app configuration, then
:infinity.
What Gets Compacted
Continuum compacts completed effect shapes only:
side_effectand fast-pathsignal_receivedbecome one compacted step.activity_scheduledplusactivity_completedoractivity_failedbecome one compacted activity step.signal_awaitedplus the winningsignal_receivedor timeouttimer_firedbecome one compacted await step.timer_startedplustimer_firedbecome one compacted timer step.
Pending scheduled events are not covered by a snapshot. The snapshotter stops at the last complete step and leaves any incomplete tail in raw history.
Snapshot steps require a recorded command_id. Histories from before structured
command identity, or manually injected events that omit it, are skipped rather
than compacted. This is deliberate: a snapshot step without command identity
would match too broadly and could hide replay drift.
Operational Notes
Keep snapshots disabled unless you have a workflow whose replay cost is dominated by old journal history. For high-value workflows, run replay tests both with and without snapshots and compare results.
The table is continuum_snapshots. Payloads are opaque Erlang external terms
inside a versioned Continuum envelope. v0.4 writes format version 1, stores
that value in continuum_snapshots.format_version, and still reads legacy
v0.2/v0.3 unversioned payloads as version 1. Future snapshot shape changes
must either decode version 1 or raise a clear unsupported-format error.
Snapshots are not a deserialization boundary for untrusted input. Continuum decodes snapshot blobs that it previously wrote to the application's database; do not accept arbitrary external snapshot payloads.