Monitor Salesforce Limits on a Dashboard

Over the last few months, we have been doing more and more in Salesforce. Adding new integrations, new features, new emails etc. I have been worried that we are not really watching the right things and soon, we will come into work one day and have bricked our org for a day because we have hit a hard limit.

In our offices, we display a dashboard that monitors some of the things that would give us indications that some of the features we have built are not working for one reason or another. But this just tells us if its working or not. I would also like to proactively monitor Salesforce limits that are most important to us. Luckily, there is a REST resource for Limits that allows us to monitor this.

My plan was to use this on our dashboards site so the monitor that displays our existing dashboard can cycle through this. However, according to the documentation, the user who is executing the Limits resource needs to have View Setup and Configuration and some of the Limits will require Manage User permissions. Unfortunately, for me, the user who will be executing the page can’t get these permissions. No matter how I access the resource, even when providing OAuth authentication with another user, I still am not able to execute and receive the limits appropriately. Pretty big bummer actually.

There is also a Limits class that has some cool stuff, but I don’t think this has most of what I’m looking to do. My options are to log into the dashboard monitor as a real user, and possibly allow someone to find the keyboard and get access to our org, or think of a different way to get the Limits resource data and display it on this monitor.

After kicking this around for a few weeks, going back and forth on if this was even valuable, we almost hit a limit and my decision was made for me. This not only had to be done, but needed to be displayed for all to see to help report a problem.

I decided that the easiest way to do this was to run a scheduled job at a regular interval and populate data into a custom setting. Then the page which would be available on a “hidden” public site would just render the data from the custom setting.

Quick note: some of this code probably sucks. There are most likely other ways of doing this, but I wanted to slap something together quickly so we could get this up and running. If you want to grab this code, make sure you understand what it does and think about optimizing it.

Ok, so let’s start with the REST resource. I have a class called ‘populateLimitsScheduler’ which is called as a scheduled job. I am running it every 15 minutes. The class uses ‘implements Schedulable’ so that it can be scheduled. It has an Execute method to trigger the API call, a method called populateLimits() to organize the data and save it, a method called runAPI() to access the REST resource and a wrapper for the incoming Limits. Lets start with the Wrapper:

If you execute the Limits resource by itself, you will notice that the limits will come with a name, a max and a remaining value. The Execute method will be used by the scheduled job to run the populateLimits method:

 

The ‘populateLimits’ method is where we are going to setup all of our data, assign variables and upsert into our Custom Setting:

You’ll notice that we call runAPI() and assign the values to a List of sfLimits. This method will access the Limits resource, parse the response and create a bunch of sfLimits:

This thing is REALLY complicated. I attempted to use JSON2Apex by pasting the response from Limits, but it was taking forever and the structure of the Limits response kind of makes it a pain to use. So, instead of using JSON2Apex, I created my own JSON parser for the structure of the Limits Resource. What makes it problematic is that limits are imbedded within other limits. There is probably an easy way to parse the response with JSON2Apex, but I was just having all kinds of issues and just did it on my own. This is probably the part that could use a rewrite.

ANYWAY, this method attempts to login using OAuth with a system user and then once a valid token is returned, access the Limits resource. We then parse the response from the Limits resource from the format we get and then make sfLimits out of each one. One problem that happens with this resource, is there are some Limits that are duplicated in the response under different parent Limits. This causes some funkiness but we try to resolve this later.

Once we return all of the sfLimits in runAPI to populateLimits, we put them into a Map to attempt to de-dupe based on the Limit name since we should never have more than 1 Limit with the same name anyway. After we created the Map, we create individual records in our custom setting called Limits__c and populate with objects with the variable name limitInstance. Then we just upsert a list of these based on the Name to replace the existing Limits in the custom setting. This data will just keep being replaced over and over again to get the newest numbers. Maybe some day we will redesign this to store data over time to do comparisons, but right now, I just want to show the current data. Complete code at the end of the blog post.

So after we have this code, we can schedule it every 15 minutes by running this in dev console:

So now every 15 minutes, the Limits API will be accessed, limits pulled down and saved to our custom setting.

We have Data!

Screen Shot 2017-12-17 at 4.10.52 PM.png

Now we need a page though that will display the data we want. There are 6 limits that I want to monitor based on some of our previous experience and things that most companies will probably have trouble with:

  1. Daily API Limit
  2. Daily Asynchronous Apex
  3. Hourly oData Callout Limit (External Objects)
  4. Daily Emails sent from Apex
  5. Daily Workflow Emails
  6. Hourly Scheduled Workflow

We can then just create a Page and a Controller. The controller is pretty simple:

And the page:

We are using a couple of libraries such as jQuery and Bootstrap and then also my favorite charting library, Highcharts.

Then, we get a page that looks like this:

Screen Shot 2017-12-17 at 3.54.12 PM

It is responsive with the Bootstrap and Highcharts, so looks pretty great on mobile too!

Last, we make this page available on our public dashboards site so it is accessible, but the underlying data, API access and credentials for the OAuth callout is not which is pretty cool. So now, we have our two dashboards that help our Salesforce team make sure they can easily monitor some of the things that we are important to us daily. When all is said and done, we come up with this for all to see in our IT department:

2017-12-18 10.28.18
Limits Dashboard on a wall with idea paint (note the smiley face)

populateLimitsScheduler (shoutout to  for their Superfell & Metadaddy for their consumeObject concept from JSON2Apex):

Test for our code:

Mock for our Limits callout for the test:

 


5 thoughts on “Monitor Salesforce Limits on a Dashboard

  1. Hi,

    Very knowlegeable article. I am working on a close requirement as mentioned above.

    My requirement is as mentioned below:

    Notification alert for Async Apex Execution Limits
    I want to send an alert notification when overall organisation Async Apex Execution limit reached 70%of total limit(24hrs API Limit). Say if limit is 2500 and if system already exhausted 1750 of daily Async Apex Limit out of 2500 then any alert should be send to few persons notifying that your organisation limit of Async Apex Executions have reached 70% threshold.

    Kindly help me.

    Any help will be greatly appreciated.

    Many thanks in advance

    Thanks & Regards,
    Harjeet

    Like

    1. I think you could easily do this without the batch job stuff, although it might be helpful so you’re not constantly monitoring the API usage for every transaction.

      I think if you followed a similar pattern, with either an internal page (where you didn’t need a batch) or use a batch to store the most recent limits, you could write automation based on the saved data (remaining/total) and depending on the value returned for remaining/total, send an email or something. You would need to worry about sending duplicate emails of course.

      I think all of the components are here if you wanted to do this yourself, except for the automation for the email. In my case, you may need to change the structure to a standard object instead of a custom setting and then looking for the ‘DailyApiRequests’ limit in your object and compare the two returned values like above.

      Like

    2. If you follow the pattern exactly or similarly, you should be able to do a comparison of used/available for a specific limit and take action either within the batch or after by sending an email or creating a chatter post, etc. If you do it at the time of comparison in your batch that seems easy enough but you’re going to have to write your own code for that 😉

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s