Waits, Timeouts and Recursive Workflows
In two previous separate articles I discussed Waits and Timeouts in Workflows, and Recursive Workflows. Thanks to web analytics being integrated in my CRM, I know these are two of the more popular articles I’ve written this year (you can click the image to go to the archive of all workflow articles on the Trick Bag):
These are actually closely related topics, in the sense that it’s hard to imagine a recursive workflow that doesn’t at least wait for a little bit before calling itself again! Also, Zarko Radevic posted the following question on the Waits and Timeouts article:
I find your post very useful and I would appreciate if you responded to my question: What if I set a Timeout step and someone changed the date field to which the step is bound.
So I thought I’d drill down on these related topics and solve a common business problem at the same time: how to implement a business process in which an opportunity owner receives a reminder when an opportunity becomes past due, then gets a few more periodic reminders (perhaps with each one becoming a little more strident), and finally, after a specified number of reminders, the opportunity simply gets closed out.
This turns out to be best solved with a recursive workflow with a couple of different timeout conditions, and as a bonus it answers Zarko’s question above, so let’s dive in.
Opportunity Checker Release .9
Here’s a first pass at this. It doesn’t do everything we need it to (hence the .9 release status), but it does a nice job of illustrating how Wait until Timeout works. Let’s start out by seeing what the workflow looks like in the workflow design environment:

The workflow starts with a Timeout condition, displayed in the design environment as:
“Timeout until Days: 1 Before Opportunity:Est. Close Date then”
After publishing the workflow, I’ll create two opportunities to see how it works:
- Opportunity 1 has an estimated close date a couple weeks in the future.
- Opportunity 2 gets created with an estimated close date equal to today’s date.
Navigating to Opportunity 1 and clicking on Workflows in the Details section, we see that it’s got a Status Reason value of Waiting, as expected:

Double-clicking on the workflow instance (referred to as a System Job in this context), we see it right there on the Timeout condition:
For Opportunity 2, however, the workflow’s got a Status Reason of Succeeded:
And if you open up the workflow instance, it’s easy to see why:

The “Timeout until” condition evaluated to “true” since I entered a value of 6/21 for the estimated close date, and today is 6/21. As soon as the condition evaluates to true, the workflow proceeds.
This is a simple example, but here are a couple of important points a simple example helps to clarify:
- It functions like a “Timeout while CurrentDate < (Est. Close Date – 1)”. So if you create a new record where the condition is already met (you enter an est. close date in the past, for example) the condition evaluates to true and it proceeds.
-
While waiting, what happens if the test field (Est. Close Date) changes? (This was Zarko’s question.) What happens is: the workflow engine fires up, the status reason changes to In Progress…then it re-evaluates the condition with the new Est. Close Date value, and does the right thing:
- If it’s not true (CurrentDate still < (Est Close Date – 1) goes back into Waiting…
- If it is true (CurrentDate >= (Est Close Date – 1), proceeds…
I think the best way to illustrate the last point is to go back and update Opportunity 1, giving it an est. close date of today, or yesterday. If you do that, save the record and are quick enough, you can watch the system job cycle through the Status Reason values of Waiting for Resources…In Progress…then Succeeded. I was only quick enough to get the last two:


I think of it like this:
- The workflow hits the Timeout and if the condition is not met — in our example, if the current date is less than (Est. Close Date – 1) – it waits.
- If the value of the field included in the condition – here, Est. Close Date – changes, the engine fires up and checks the condition again. If the change causes the condition to evaluate to true, it continues, otherwise, it resumes waiting.
So now that we’ve got the basics down, and shed a little light on how the Timeout works, let’s complete the “Opportunity Checker” workflow, adding the logic to take appropriate action for these overdue/escalation scenarios.
Opportunity Checker Release 1.0
Here I’ll describe a workflow that implements escalating logic on an opportunity record and has some similarity to the escalating logic for cases I described in the earlier article. The main differences of this version compared to the .9 release are:
- After going into the wait state, it actually does something! It assigns a series of “overdue reminder” tasks as its escalating action. In the real world you might want to send e-mails (workflows can do that, of course), but when I’m testing these things in a sandbox environment I usually use tasks since I don’t have to configure e-mail.
- After the overdue reminder task is created, the workflow does another kind of wait condition – this one is
- It uses a custom “counter” attribute (type of int) on opportunity to keep track of how many times
Here are the basic workflow properties:

It needs to be available to run as a child workflow so it can call itself recursively. You may or may not want something like this to run automatically when a record is created – that’s a business decision – but when you’re testing it it’s convenient to make it available on demand so you can manually apply it to existing records. In the more or less completed version here, I’ve turned off the on demand option.
For the logic of this workflow, I divided it up into two stages. Any workflow in CRM 4 can have stages, and stages by themselves don’t do anything other than organize your workflows and make them more readable. Here’s my first stage:

The first thing it does is check the “Overdue Counter” attribute; if it’s empty it’s the first time in so it sets it to 1, otherwise it increments it by 1.
Next, it checks to see how many reminders have been created; if more than 3 it checks the status and if it’s still open, a final “post-mortem” task gets created and the opportunity record gets closed out with a status reason of “Canceled”.
The main logic of the workflow is in my stage 2 (augmented immensely, no doubt, by my Paint wizardry):

Here, the first thing that happens is the Wait condition: I refer to the timeout as the “outer loop” (you’ll see why in a minute), and as soon as the condition is satisfied, the (that is, we’re either past or close to the estimated close date), the workflow proceeds to an If/Otherwise block characteristic of workflows like these.
If the opportunity’s still open, the workflow creates the “one-day followup” reminder task, then it does another Timeout; this section I refer to as the “Inner loop”. This one uses the special Workflow Execution Time variable. (You’ll see that in the Specify Condition dialog if you select Workflow in the Look for drop-down in the Dynamic Values section.) This is an important variable to understand, since for a workflow like this one it’s really the way to go: after you assign a task or send a reminder e-mail, you need to give the sales rep a chance to do something!
After this timeout, the workflow proceeds to another check status block, with the same basic logic as in the outer loop (if still open, do something, otherwise, stop the workflow). The main difference is in the “something” that gets done: here’s where the workflow calls itself recursively, in the event the opportunity’s still open.
Notice I’ve got the timeout value set to 1 minute. Again, that’s for testing purposes only; in the real world that’s a business decision, but one day seems reasonable. In any event, remember that if the timeout is longer than 60 minutes you’ll avoid the “infinite loop detector”, and so you could have a workflow recurse as many times as you like.
What happens when you create an opportunity record and the workflow runs? The workflow waits as long as it needs to, until the “overdue” condition is met, and then things start to happen. For example, to get some immediate feedback, I created a new opportunity with an estimated close date of today, and checked up on the opportunity about 5 minutes later. It was closed out (by the workflow), and a few key details are summarized in the following screenshots:

Here you can see the workflow running recursively – notice the “Started On” values of each successive instance.

I put the custom attribute “Overdue Counter” on the Administration tab for testing purposes, and you can see it eventually got incremented to 4 before the workflow created the post-mortem task and canceled out the opportunity.

Finally, here are the tasks the workflow created. Notice the post-mortem task has a different subject than the others. You could also put the “Overdue Counter” in the subject if you wanted to make that bit more obvious.
| OK. Long article on what to me is an interesting topic. If you got this far, chances are good you found it interesting also. If so, and you need to learn even more, check out the one-day live online class I deliver on the topic: | Need to learn about workflows in Dynamics CRM? Consider my one-day live online class, Building Workflows in Dynamics CRM, which also includes a copy of my book on the topic. |




Vaidy Said,
June 22, 2010 @ 12:49 pm
I am new to CRM and this blog has been a terrific learning place.
This article especially is awesome. Thanks for sharing with us.
Vaidy
Richard Knudson Said,
June 22, 2010 @ 2:02 pm
Hi Vaidy — Thank you so much! Some of my favorite articles come from questions I get asked by readers, so if you ever get stuck on something, feel free to ask about it!
Richard
dml Said,
August 20, 2010 @ 8:18 am
Hi, Richard
I am stuck. I need a simple workflow that will run on one attribute based on a user populating another attribute (end date) that is eual to current system date.
I have a wait condition set up initially in the workflow but can’t figure out exactly how to get the field to equal current system date.
Would appreciate your assistance.
Sorry, if this is a dup submission…I could not see my original question posted.
Olivier Furnemont Said,
December 8, 2010 @ 2:19 am
Hi Richard,
Thanks for sharing this information, I was wondering about the TimeOut functionality in Microsoft CRM and got the answer I wanted!
Do you mind if I link your site to mine?
Br,
Oliver
Brandon Said,
January 12, 2011 @ 9:22 am
Good Morning,
What is the resource draw on the ‘Wait’ Condition since it is always checking the date? If we applied the above logic to 2,000 records or 20,000 records what are the resource requirements?
V/r
Brandon
Mark Said,
March 16, 2011 @ 6:58 pm
Hi Richard, thanks for all the useful info on the website and in your book. I have a workflow query. I have a service go live date in crm and have created customer retention tasks to work on 1, 3, 6, 9, & 11 months after that date. I would like to recreate the process loop for the following year and re ran the process as a child workflow, but the dates on the new tasks were the same as before and not 1 year a head..I know that makes sense but wondered how I could do it properly.
Gaston Prereth Said,
May 16, 2011 @ 3:35 am
Firstly, Thanks Richard for all the time and effort put into spreading your knowledge, I know 20x more people than will have commented will have found this article useful.
Mark, Sounds to me like you need to have a look at the task record you are generating. My guess is that you are using the “created on” field which is why the dates are for last year (unless i’ve misunderstood the issue.)
Ok, My query here is about how much pressure this would put on the system. I don’t really know how much a timed out workflow slows the system down or how many is a welcome load.
I have a similar (if slightly more simplistic) workflow to check the date quotes are generated and to prompt people before they are a month old (when our quotes cease to be valid). What i’m worried about is that if we go through a particular purple patch, a lot of quotes will get generated and the workflow will run for 3/4’s of the month (whether the quote is accepted or not).
The solution would be, I think, to set up a child workflow to wait 5 days, check the status and stop if closed otherwise wait another 5 days.
I just don’t know whether there is any point in doing that? If timed out workflows have a neglagible affect on the system it seems like a waste of time.
Gaston
Mario Said,
August 19, 2011 @ 7:50 am
I did not even know that the Timeout existed in CRM. Thank you for this great article, I will be able to optimize my workflows with this. I do have a question for you and I’m hoping that you can help me.. I have a request to build a workflow where
date is greater/equal to 942 days.
Prompt for letter print out.
Then in 120 days, if date not has not been updated by the user then update Requestor Status to “Exp”. (internal field)
(or could we just do date plus/greater/equal to 1062 days?)
My problem is that I dont see an option to choose more than 24 months when setting a future date lookup.
any help or guidence would be appreciated.
Saurabh Gupta Said,
December 21, 2011 @ 11:49 pm
Hi Richard,
Your blogs are very informative. It helped me a lot.
I request you if you could through some light on:
1. Activity Count
2. Activity Count including Process
3. Execution Time
Regards,
Saurabh Gupta
India