After seeing presentations that assert that “Workflow runtime is lightweight” and not finding any concrete numbers to support that claim I decided to do some of my own profiling.

 

Here is what I’ve done, measuring memory utilization after every step (the displayed results are the difference, in bytes, of current memory consumption minus one at the previous check point):

  1. Create a simple Windows app -- one form with a couple of buttons on it.
  2. Get the baseline memory utilization
  3. Instantiate workflow runtime using early binding

System.Workflow.Runtime.WorkflowRuntime wr = new System.Workflow.Runtime.WorkflowRuntime();

  1. Start runtime:

wr.StartRuntime();

  1. Create a basic (nothing except for the initial state) state machine workflow:

wr.CreateWorkflow(typeof(RulesAndWorkflows.Workflow1));

  1. Stop runtime and dispose the object:

wr.StopRuntime();

wr.Dispose();

wr = null;

 

Here are the early-binding results (in release mode):

  • Baseline private bytes: 18,194,432
  • Instantiate runtime: 1,232,896
  • Start runtime: 1,724,416
  • Creating empty workflow (loads Activities and ComponentModel assemblies): 2,203,648
  • Stop runtime, but do not unload assemblies: 0

 

Note: running same code again results in no additional memory consumption:

  • Instantiate runtime: 0
  • Start runtime: 0
  • Creating empty workflow (loads Activities and ComponentModel assemblies): 0
  • Stop runtime, but do not unload assemblies: 0

 

 

In the second type of test I wanted to profile the memory utilization when loading assemblies “manually”, i.e. using late binding:

  1. Using the same application, get the baseline memory utilization
  2. Instantiate runtime:

AppDomain.CurrentDomain.CreateInstanceAndUnwrap("System.Workflow.Runtime", "System.Workflow.Runtime.WorkflowRuntime");

  1. Load System.Workflow.ComponentModel assembly:

AppDomain.CurrentDomain.Load("System.Workflow.ComponentModel");

  1. Load System.Workflow.Activities assembly:

AppDomain.CurrentDomain.Load("System.Workflow.Activities");

 

Below are the late-binding results (in release mode, without workflow creation):

  • Baseline private bytes: 14,028,800
  • Late-bound runtime instantiation: 4,689,920
  • Load System.Workflow.ComponentModel assembly: 204,800
  • Load System.Workflow.Activities assembly: 708,608

 

 

Now, armed with data, you can draw your own conclusions about the WF footprint.  Of course, keep in mind, that the “real-life” applications will have significantly larger baseline memory utilization than my primitive sample did…