Skip to content
Thyme Docs

Persistent Storage

ctx.storage is a mutable JSON object scoped to one executable. Two executables using the same function have independent state. Change properties in place; do not depend on module globals or sandbox files between invocations.

ctx.storage.lastCheckedAt = new Date().toISOString()
ctx.storage.checks = Number(ctx.storage.checks ?? 0) + 1

When state is committed

OutcomeState behavior
Task returns canExec: falseSuccessful run/onSkip state is committed.
Transaction confirmsTask state is committed, then successful onSuccess state is committed.
Submission fails and onFail runsCallback starts from pre-run stored state; successful callback changes can commit.
Task throwsDo not rely on run or onError mutations being persisted.
Cloud simulationNo storage commit.

A successful transaction cannot be undone by a later callback or storage failure. Use onSuccess for checkpoints that mean “confirmed on-chain,” and monitor storage-commit errors separately. See lifecycle callbacks.

JSON rules

The root must be a plain JSON object, up to 100 MiB when serialized. Nested JSON arrays and objects are allowed. BigInts, undefined, non-finite numbers, negative zero, and unsafe keys (__proto__, constructor, prototype) are rejected. Store large integer values as decimal strings.

This is non-secret state. Credentials belong in secrets. Keep state compact so loading and serializing it fit the execution budget.

Local storage

Local runs start with functions/<task>/storage.json. By default the CLI prints the produced state without saving it:

thyme run my-task
thyme run my-task --persist

--persist writes successful output back to the local file. Local and cloud state are separate; upload does not seed executable state from storage.json.

Cloud edits and concurrency

Cloud storage uses a lock during execution and optimistic version checks on edits. Console and management commands can read, replace, patch, or reset state subject to the API's supported operations and authorization. Fetch the current version before changing it; if it changed, reread and reconcile rather than overwriting blindly.

The management API has a 16 MiB transport limit, smaller than the 100 MiB runtime cap. Large runtime state may therefore be unavailable through management storage endpoints.

When a webhook execution commits changed state, its result retains an immutable snapshot for 24 hours. Snapshots up to 1 MiB are inlined; larger ones use a temporary download URL. Subsequent executions do not modify that retained snapshot.

Follow persisting state for a checkpoint example.