elsa-workflows / elsa-workflows/elsa-foundation

Input snapshot materialization is O(state) per activity (full paged traversals per hop)

Open
#1,306 0 comments 0 reactions 0 assignees View on GitHub
performance ready-for-agent
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.