elsa-workflows / elsa-workflows/elsa-foundation
Input snapshot materialization is O(state) per activity (full paged traversals per hop)
- Dominant language
- C#
- Stars
- 5
- Forks
- 1
- Avg merge
- 3h 52m
- Merged PRs (30d)
- 212
Description
## Problem
Input snapshot materialization performs full paged traversals of runtime state **per activity execution**:
- `RuntimeActivityInputSnapshotMaterializer.MaterializeAsync` (`src/Elsa/Workflows/Runtime/Services/RuntimeActivityInputSnapshotMaterializer.cs:32-39`) calls `ListAllDurableValueStatesAsync` **and** `activityExecutionStateStore.ListAllAsync` **and** `BuildVisibleFramesAsync` per `StartActivity`.
- `WorkflowInvokeActivitySchedulerWorkHandler.cs:174` repeats `ListAllDurableValueStatesAsync` per `InvokeActivity`.
- Same pattern in `WorkflowParentActivityCompletionSchedulerWorkHandler.cs:330`, `WorkflowNotifyParentActivitySchedulerWorkHandler.cs:231`, `WorkflowRetryActivityBoundarySchedulerWorkHandler.cs:73`, `WorkflowIntrinsicExecutor.cs:566`.
These are paged full traversals (`RuntimeStatePagingExtensions`, page size 100), so a workflow with 500 durable values pays 5+ store round-trips *per activity*, and the cost grows with execution history × activity count. This O(state) × O(activities) term is not covered by coalescing, fusion, or the executable cache.
## Likely fix
ADR 0031 item (b) — the burst-scoped reconstructible heavy-object cache — is the designed-but-unshipped mechanism for exactly this: memoize the durable-value/activity-state baselines per drain (single-writer invariant makes this safe), invalidated on flush, byte-identical fallback when cold. Spec 131 (coalesced inspection-read memo) is the pattern to follow.
Also measured as the top per-hop lever after fusion: at identical hop/commit counts the `Set` intrinsic is ~2.2× faster than a fused CLR leaf; the delta is DI activation + input-snapshot materialization + attempt claim (`docs/reports/execution-model-comparison-2026-08.md:1004-1010`).
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with ADR 0031 item (b) and Spec 131, then inspect RuntimeActivityInputSnapshotMaterializer.cs and the five scheduler/executor call sites named in the issue. Trace the paged state reads and the single-writer drain lifecycle. Done means the baselines are memoized per drain, invalidated on flush, and cold behavior remains byte-identical.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- backend, performance
- Issue type
- Refactor
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100