Skip to main content

Side Effects

Workflow code must be deterministic because Cadence replays it from event history. workflow.side_effect and workflow.mutable_side_effect let a workflow capture a short, non-deterministic calculation and record its result in history.

Use an activity instead when the operation performs I/O, can take significant time, needs retries, or changes an external system.

Samples​

SampleDescriptionCode
Side-effect testsDemonstrates recorded values, replay behavior, updates, and stable mutable IDstest_context_side_effect.py

side_effect​

side_effect runs a synchronous callback once, records its result as a workflow marker, and returns the recorded result during replay without calling the callback again.

import uuid
from cadence import workflow

request_id = workflow.side_effect(
lambda: str(uuid.uuid4()),
str,
)

The second argument is the result type used by the workflow's data converter.

The callback must not mutate workflow state. Only the returned value is recorded, so other callback effects are not reproduced during replay.

mutable_side_effect​

Use mutable_side_effect for a value that may change during a long-running workflow, such as a dynamic configuration value. The SDK records the first value and records a new marker only when the updated callback says the value changed.

limit = workflow.mutable_side_effect(
"processing-limit",
read_processing_limit,
int,
lambda previous, current: previous != current,
)

The arguments are:

ArgumentDescription
idStable, non-empty identifier for this value within the workflow execution.
fnSynchronous callback that obtains the current value.
result_typeType used to deserialize recorded values.
updatedCallback that receives (previous, current) and returns True when the current value should be recorded.

During replay, neither fn nor updated runs. The SDK returns the value stored in workflow history.

Determinism rules​

  • Call side effects in the same logical order on every replay.
  • Do not conditionally add or remove a side-effect call without using workflow versioning.
  • Keep callbacks fast and free of external mutations.
  • Do not catch a callback failure and substitute a different non-deterministic path.
  • Keep the mutable_side_effect ID stable for the life of the workflow execution.