I am working on implementing a timed RecordType change in salesforce. I have an object that when created needs to change its RecordType after a certain number of days. The only catch is that if a particular field on the object is filled out then the change should not happen. I am just wondering what would be the best way to go about implementing this. There could potentially be 100,000 of these objects in a worst case scenario and possibly larger.

My initial reaction was to look into the scheduled workflow that would change the record type X number of days after but I am unsure if this workflow will turn off when the criteria changes. My second thought was to use scheduled apex and have a segment of code run every night and change the RecordTypes but I am worried about the scalability of this with large volumes of records.

Does anyone have a recommendation of an apporach to tackle this problem? I would appreciate any input or advice on a direction to take. Thanks


Time based workflow is perfect for this. The workflow turns off automatically when the criteria changes. Scheduled Apex will also work, but isn't needed. Batch Apex would ensure you can scale to large data volumes.

From Help & Training

Time-dependent actions remain in the workflow queue only as long as the workflow rule criteria are still valid. If a record no longer matches the rule criteria, Salesforce removes the time-dependent actions queued for that record.

For example, an opportunity workflow rule may specify:

  • A criteria set to “Opportunity: Status not equals to Closed Won, Closed Lost.”
  • An associated time-dependent action with a time trigger set to seven days before the opportunity close date.

If a record that matches the criteria is created on July 1st and the Close Date is set to July 30th, the time-dependent action is scheduled for July 23rd. However, if the opportunity is set to “Closed Won” or “Closed Lost” before July 23rd, the time-dependent action is automatically removed from the queue.

  • 1
    Sometimes Scheduled/Batch Apex is needed to prevent a ton of workflow rules just to change the record type, since you can't use a formula to dictate the new type. That said, for simple cases, this is indeed perfect. – sfdcfox Nov 6 '13 at 23:38
  • 1
    And you can easily test it by using the Time-Based Workflow search to check records get added/removed. – BritishBoyinDC Nov 6 '13 at 23:42
  • @sfdcfox So if I only have one rule that will apply to all of the custom objects (it is similar to resetting it to a default record type) then it makes since to just use the workflow? Correct? – Chris Nov 7 '13 at 16:03
  • 1
    @Chris My usual recommendation is "configuration first", meaning don't code if you can avoid it. You have to consider the potential consequences, however. If there are triggers on the object, and you use a workflow rule field update, they will fire twice (the "echo" effect). If this is undesirable, use a trigger (or modify the existing trigger). Otherwise, writing a trigger for simple logic is probably overkill, not to mention it would take longer to make simple changes to the logic because of deploys and runAllTests. In this case, use workflow rules. Common sense is the order of the day. – sfdcfox Nov 7 '13 at 16:24

To accomplish a number of date-dependent pieces of work we run a Scheduled Job - a class that implements Schedulable - every night.

That job can then kick-off a chain of classes that implement Database.Batchable. These avoid governor limit issues by breaking their work up into multiple batches passed to the execute method, each with its own governor limits. The work in these can be further reduced by ensuring that only the relevant objects are considered (in the start method), in your case only the objects whose CreatedDate match "today" minus the "certain number of days" (plus the particular field logic). By working in Apex you have full control over the logic you execute.

Take care to allow this code to be re-run from the developer console in case days are missed or errors cause part of the process to be missed. And ensure that you report errors - using try/catch and emailing them in the Database.Batchable finish method is one approach (providing state is preserved by implementing Database.Stateful; but note that some exceptions can't be caught).

  • 1
    Except, depending on the specific use case, a workflow is more appropriate (the principle of configuration over code). – sfdcfox Nov 6 '13 at 23:37
  • 1
    I guess I have a preference for code and unit tests (that my continuous integration server runs multiple times a day) over configuration and no tests. And sometimes the configuration approach isn't capable enough. But you are right that other times it is. – Keith C Nov 6 '13 at 23:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.