A large number of for each or do until iterations in a Flow Designer flow can cause memory and performance issuesDescriptionFlow designer flows keep nearly all state in memory while executing. Flows with many executed steps may cause memory and performance issues. The most common cause is a for each or do while loop that iterates many times. The state from each iteration is held in memory during execution and eventually memory will run low as loop iteration continues. Redesigning a flow to "divide and conquer" by using dynamic subflows or the scriptable flow api can greatly reduce memory usage. This approach is described in the workaround.Steps to Reproduce Warning-- following these steps may cause slowness and memory issues on your instance. Do not do this on production. 1. Set system property sn_flow_designer.max_iterations to 100000. 2. Set system property com.glide.hub.flow_engine.op_executions_between_saves to 0. 3. Create an action called "get_big_string" A. Add an integer input "length". B. Add a String output "s". C. Add a script step with this script: (function execute(inputs, outputs) {var len = parseInt(inputs.length);var text = "";var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";for (var i = 0; i < len; i++) text += possible.charAt(Math.floor(Math.random() * possible.length));outputs.s = text;})(inputs, outputs); 4. Create a flow called "loop": A. Trigger when problem created with Problem Statement = loop B. Update Problem Record action and set Trigger->Problem Record->Problem Statement = 0 C. Add Do Until loop D. Inside loop Look Up Record on Table Problem where Sys ID = Trigger->Problem Record->Sys ID E. Also inside loop Update problem record from previous action setting Problem Statement = scripted with this script-- var count = parseInt(fd_data._3__look_up_record.record.short_description); return (count + 1); F. Also inside loop call action get_big_string with input length = 1000000 G. Also inside loop Log "Iteration " (problem record from step E)->Problem Statement " big string is " output s from step F. Apply a substring transformation to the big string for characters 0 through 10. H. Set until condition for loop to be (problem record from step E)->Problem Statement "is" "2000.0". 5. Run the flow using the test button with "Run test in background" selected. Observe that there are memory issues (look at Servlet Memory on /stats.do or use a profiler). In my testing I saw an error "Transaction cancelled: Available memory is almost depleted" on iteration 918 after running about 40 minutes. If you do not see issues add more log actions with the problem description to the for each loop.WorkaroundThe workaround is to refactor the flow to take the steps inside the for each loop and move them into a separate subflow. Then either:1) Create an action with a script step that used scriptable flow api to call the subflow (sn_fd.FlowApi.executeSubflow(...)). Call this action inside your loop.2) Use dynamic subflow to call the subflow. Call this subflow inside your loop.Either option will cause the subflow execution to occur in a separate context, dividing up the steps and reducing the maximum memory used at any one time. You will know it is working by looking at sys_flow_context table and seeing that a context is created for the parent flow and then subsequent contexts are created for the subflow on each iteration. To fix the flow created in the "Steps to reproduce" section-- 1. Create a subflow called "loop_subflow": A. Add a String input "problem_id" B. Add a String output "count" C. Add an action Look Up Record with table Problem and condition Sys ID is Input->problem_id D. Add an action Update problem record from previous action setting Problem Statement = scripted with this script-- var count = parseInt(fd_data._1__look_up_record.record.short_description); return (count + 1); E. Add an action to call action get_big_string with input length = 1000000 F. Add an action to Log "Iteration " (problem record from step DE)->Problem Statement " big string is " output s from step F. Apply a substring transformation to the big string for characters 0 through 10. G. Add Assign Subflow Outputs and set output count to problem record from step DE)->Problem Statement H. Publish subflow. 2. Create an action "call_loop_subflow". A. Add a String input "problem_id" B. Add a String output "count" C. Add a script step: (function execute(inputs, outputs) { var subflow_inputs = {};subflow_inputs['problem_id'] = inputs.problem_id;var result = sn_fd.FlowAPI.executeSubflow('global.loop_subflow', subflow_inputs);outputs.count = result['count']; })(inputs, outputs); D. Publish action 2. Copy the flow "loop" to "Copy of loop". 3. Remove all actions inside the "Copy of loop"'s Do Until loop. 4. Inside the Do Until call the action "call_loop_subflow". Pass in the Trigger->Problem Record->Sys ID as the input. This should be the only action inside the do until loop. 5. Alter the Do Until condition to be action output "count" "is" "2000.0" 6. Run the copy of the flow 7. Observe that it does not fail with a memory error. Further inspection using a heap dump should show the memory usage is reduced. Related Problem: PRB1407971