diff --git a/src/core/Elsa.Abstractions/Events/WorkflowExecuted.cs b/src/core/Elsa.Abstractions/Events/WorkflowExecuted.cs
index 15aa3cc10..d1a9e60b4 100644
--- a/src/core/Elsa.Abstractions/Events/WorkflowExecuted.cs
+++ b/src/core/Elsa.Abstractions/Events/WorkflowExecuted.cs
@@ -5,7 +5,7 @@ namespace Elsa.Events
///
/// Published when a burst of execution finished.
///
- public class WorkflowExecuted : WorkflowNotification
+ public class WorkflowExecuted : WorkflowNotification
{
public WorkflowExecuted(WorkflowExecutionContext workflowExecutionContext) : base(workflowExecutionContext)
{
diff --git a/src/core/Elsa.Abstractions/Events/WorkflowExecuting.cs b/src/core/Elsa.Abstractions/Events/WorkflowExecuting.cs
new file mode 100644
index 000000000..dc81ca672
--- /dev/null
+++ b/src/core/Elsa.Abstractions/Events/WorkflowExecuting.cs
@@ -0,0 +1,14 @@
+using Elsa.Services.Models;
+
+namespace Elsa.Events
+{
+ ///
+ /// Published when a workflow is about to be executed.
+ ///
+ public class WorkflowExecuting : WorkflowNotification
+ {
+ public WorkflowExecuting(WorkflowExecutionContext workflowExecutionContext) : base(workflowExecutionContext)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/core/Elsa.Core/Handlers/PersistWorkflowContext.cs b/src/core/Elsa.Core/Handlers/PersistWorkflowContext.cs
new file mode 100644
index 000000000..92210fb82
--- /dev/null
+++ b/src/core/Elsa.Core/Handlers/PersistWorkflowContext.cs
@@ -0,0 +1,46 @@
+using System.Threading;
+using System.Threading.Tasks;
+using Elsa.Events;
+using Elsa.Models;
+using Elsa.Services;
+using Elsa.Services.Models;
+using MediatR;
+
+namespace Elsa.Handlers
+{
+ public class PersistWorkflowContext : INotificationHandler, INotificationHandler
+ {
+ private readonly IWorkflowContextManager _workflowContextManager;
+
+ public PersistWorkflowContext(IWorkflowContextManager workflowContextManager)
+ {
+ _workflowContextManager = workflowContextManager;
+ }
+
+
+ public async Task Handle(WorkflowExecuted notification, CancellationToken cancellationToken)
+ {
+ var workflowExecutionContext = notification.WorkflowExecutionContext;
+ var workflowInstance = workflowExecutionContext.WorkflowInstance;
+ workflowInstance.ContextId = await SaveWorkflowContextAsync(workflowExecutionContext, WorkflowContextFidelity.Burst, false, cancellationToken);
+ }
+
+ public async Task Handle(ActivityExecuted notification, CancellationToken cancellationToken)
+ {
+ var workflowExecutionContext = notification.WorkflowExecutionContext;
+ var activityBlueprint = notification.Activity;
+ workflowExecutionContext.WorkflowInstance.ContextId = await SaveWorkflowContextAsync(workflowExecutionContext, WorkflowContextFidelity.Activity, activityBlueprint.SaveWorkflowContext, cancellationToken);
+ }
+
+ private async ValueTask SaveWorkflowContextAsync(WorkflowExecutionContext workflowExecutionContext, WorkflowContextFidelity fidelity, bool always, CancellationToken cancellationToken)
+ {
+ var workflowContext = workflowExecutionContext.WorkflowContext;
+
+ if (!always && (workflowContext == null || workflowExecutionContext.WorkflowBlueprint.ContextOptions?.ContextFidelity != fidelity))
+ return workflowExecutionContext.WorkflowInstance.ContextId;
+
+ var context = new SaveWorkflowContext(workflowExecutionContext);
+ return await _workflowContextManager.SaveContextAsync(context, cancellationToken);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/core/Elsa.Core/Handlers/RefreshWorkflowContext.cs b/src/core/Elsa.Core/Handlers/RefreshWorkflowContext.cs
new file mode 100644
index 000000000..ea6b67edb
--- /dev/null
+++ b/src/core/Elsa.Core/Handlers/RefreshWorkflowContext.cs
@@ -0,0 +1,51 @@
+using System.Threading;
+using System.Threading.Tasks;
+using Elsa.Events;
+using Elsa.Models;
+using Elsa.Services;
+using Elsa.Services.Models;
+using MediatR;
+
+namespace Elsa.Handlers
+{
+ public class RefreshWorkflowContext : INotificationHandler, INotificationHandler
+ {
+ private readonly IWorkflowContextManager _workflowContextManager;
+
+ public RefreshWorkflowContext(IWorkflowContextManager workflowContextManager)
+ {
+ _workflowContextManager = workflowContextManager;
+ }
+
+ public async Task Handle(WorkflowExecuting notification, CancellationToken cancellationToken)
+ {
+ var workflowExecutionContext = notification.WorkflowExecutionContext;
+ workflowExecutionContext.WorkflowContext = await LoadWorkflowContextAsync(workflowExecutionContext, WorkflowContextFidelity.Burst, false, cancellationToken);
+ }
+
+ public async Task Handle(ActivityExecuting notification, CancellationToken cancellationToken)
+ {
+ var workflowExecutionContext = notification.WorkflowExecutionContext;
+ var workflowBlueprint = workflowExecutionContext.WorkflowBlueprint;
+ var activityBlueprint = notification.Activity;
+
+ if (workflowBlueprint.ContextOptions?.ContextFidelity == WorkflowContextFidelity.Activity || activityBlueprint.LoadWorkflowContext || workflowExecutionContext.ContextHasChanged)
+ {
+ workflowExecutionContext.WorkflowContext = await LoadWorkflowContextAsync(workflowExecutionContext, WorkflowContextFidelity.Activity, activityBlueprint.LoadWorkflowContext || workflowExecutionContext.ContextHasChanged, cancellationToken);
+ workflowExecutionContext.ContextHasChanged = false;
+ }
+ }
+
+ private async ValueTask