12

I realize there are plenty of ways to try to avoid hitting limits in the first place, but when it comes to features with 24 hour limit plans, how can you know if you're getting close to them? And since managed packages also share these limits with non-managed code, how can you determine if it's "ok" to fire off more emails or "ok" to launch additional @Future calls?

In a clean dev org, in an anonymous Apex window, I executed the following:

system.debug('Total Future Calls Allowed: ' + system.limits.getLimitFutureCalls());
system.debug('Total Emails Allowed: ' + system.limits.getLimitEmailInvocations());

Resulting in:

14:06:16.023 (23004000)|USER_DEBUG|[1]|DEBUG|Total Future Calls Allowed: 10
14:06:16.023 (23130000)|USER_DEBUG|[2]|DEBUG|Total Emails Allowed: 10

So the total email and future calls allowed relates to the current execution context, not the org. Also, batch Apex permits 250,000 batch executions in a 24 hour period but doesn't even have a System.Limits method (probably because the 5-concurrent execution limit is self limiting org-wide).

I've looked around at the Organization object and elsewhere but can't find anything. Is there a way to determine total allowed and currently available futures, emails and batch Apex executions?

2
  • Here's a previous response salesforce.stackexchange.com/questions/3380/… Commented Dec 13, 2012 at 6:58
  • Since my question deals with 24hr limits in general, and the previous response is @Future-specific, I'm giving the right answer to Andrew and closing this out. Otherwise I'd just close it out.
    – Adam
    Commented Dec 13, 2012 at 17:11

4 Answers 4

13

The Limits class as you have started to discover is only for the current request and does not provide any org wide limit information. Salesforce have partially addressed this with emails, but as far as I can see there is nothing for Batch Apex or @future. Though I have included some thoughts below on both.

Emails. There is a couple of methods on the Messaging class called reserveSingleEmailCapacity and reserveBulkEmailCapacity. They don't tell you how much is left, but will stop your app if your about to exceed it. The downside is that it throws uncatchable exceptions, if that would be an issue to you check out this answer.

Batch Apex / @Future. There is no equivalent to the reserve methods above here, nor any way to query the current value. So here are some general thoughts to consider, both in terms of your answer and also avoiding the limit...

  • Schedulable If you are issuing a lot of Batch Apex or @future calls from triggers or buttons, consider implementing a Scheduler to aggregate the work into a single job and time slots throughout the day. You can use 'processed' indicators on your records to implement your own queue approach for records. This does have an impact on user experience, though under heavy load the platform queues and they don't always get a rapid response from the job completing anyway.
  • Custom Throttler. Similar to above but layers your own Queuing around Batch Apex. Create a Custom Object to register your jobs and allow the Throttler scheduled job (goes off every 15 mins say) to read a certain amount from the queue and start the jobs itself, then go back to sleep. So instead of calling Database.executeBatch directly from your triggers or buttons, you insert a record to this object with the required details. You could probably make a reasonable job of this being quite generic, via the new Type.forName and Type.newInstance methods actually. The downside with this is that this only applies to your use of jobs, and do not throttle others, so depends on what else is in the org.
  • Iterator If you have lots of Batch Apex jobs for different objects, consider if it might make sense to aggregate some of them using Iterator as the source of records to process. This will allow you to handle data of a mixed type in a single job.
  • AsyncApexJob object. You may have some joy in querying the AsyncJob object to determine activity over the last 24 hour period. I've not done this before, but seen it suggested a few times. Both Batch Apex and @future jobs appear in this object. This also contains ALL jobs, and not just yours, e.g. from other applications installed. I would say this is semi-reliable and needs testing as I am not sure when the system truncates it.
  • Custom Settings. This has also been suggest a few times, but as per the Custom Throttler, really only help if your sure your the only one contributing to the limit. There is obviously some more date and time logic here to implement as well.

Summary. My personal view is try to consider which jobs need to be 'system / app level' and which are handling 'end user requests'. The former can be scheduled to throttle job usage through aggregation of work into one job. The later, is somewhat harder, but often is negotiable with end users into a more scheduleable approach (say every 15 mins), particularly as they are already used to not getting an immediate response anyway. What remains after taking these two considerations are the jobs that really do need to be invoked more aggressively on user demand.

Ok, I feel like this has turned into a bit of best practice answer, rather than a direct one, which unfortunately is a no. Anyway I hope this helps in some way!

1
  • Great comment, Andrew. Thanks! I personally implement the throttled, scheduled, batched and mixed-type processing. I then use a class factory pattern that handles the appropriate processing depending on the current batch (limited to 1 row per batch with variable processing at each iteration). But regardless, since this is an org-wide concern, clients with other managed packages using up these limits will reduce all resource planning efforts to a "use as little as possible and hope for the best" approach. AsyncApexJob is the way, and the link techtrekker posted has a good example. Thanks again.
    – Adam
    Commented Dec 13, 2012 at 17:08
3

Instead of sending email from Apex we can send email from Workflow rule. Workflow rule has email limit of 1000xTotal Salesforce license. We can create temporary record which tracks email to be sent. Workflow rule can be written on that record to send email. Use Visualforce email template to create dynamic content. This approach has many other advantages, I have listed everything here in more detail.

Resolve 24 hour email limit error

1

No way that I'm aware of. The only approach I can think of that would approach a workaround would be to count your own code's executions in two custom settings (one for the count, one for the date of last increment so you can reset it correctly). Then you could have a configurable threshold that once you passed N executions, you do something else or wait until the next day. You'd want the N to be customer-configurable so you can adjust based on other installed apps, future changes to limits, etc.

2
  • 1
    AsyncApexJob holds the answer and Zach's example of its usage is excellent: salesforce.stackexchange.com/questions/3380/…
    – Adam
    Commented Dec 13, 2012 at 17:14
  • Cool, now I know! I hope I never have to use it to see if I've violated daily limits :)
    – jkraybill
    Commented Dec 13, 2012 at 23:59
-2

Take a look at MassMailer app API which will let you bypass any email limitations.

http://www.mansasys.com/massmailer

http://support.mansasys.com/support/solutions/articles/72737-mass-mailer-developer-guide

1
  • 1
    -1 for referencing a paid app that gets around the standard Salesforce email limits.
    – Adam
    Commented Sep 5, 2013 at 18:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .