4

I am a developer for a Salesforce org that serves as a community portal for thousands of users. We have been consulting with a large team of developers for years and everything we have is custom coded. Our pages are built using AngularJS to remotely call Apex code. We are on an Unlimited Edition org and we are nearing 90% of our total allowed code. We have a lot of callouts to external services and many times these callouts can run long.

We are now running into issues where users are seeing the "Unable to Process Request - Concurrent requests limit exceeded" error. The issue is there is so much code written by so many different developers it is hard to identify what/where the problematic code is. Sometimes users see this error when they are trying to perform a callout. Sometimes it's when they are inserting a record and triggers are firing. The long-running code issue can be anywhere in our org. Another issue is error handling has been done very poorly, so if any process does run long, we most likely are not looking for it or logging it.

Other than enhancing the logging on our callouts, I do not know where to even begin to find other problematic code. Every developer before me has written code with no regards to limits, so inefficient code can be anywhere. Is there any way or best practice to being able to analyze such a complex org and find where the problems may be? All I can think of is enhanced logging EVERYWHERE, but that may not be the best approach and would be very time consuming, especially considering how many developers we have constantly writing and pushing new code.

I have tried to replicate the issue in a sandbox however I cannot seem to get it working. I wrote Javascript to remotely call an Apex method that waits for 6 seconds. I called this remotely 11 times at once, causing 11 synchronous transactions running concurrently each longer than 5 seconds. However instead of getting the concurrent limit error, each Apex transaction just errors out with a timeout.

Any help would be greatly appreciated. I am not familiar with the majority of the code/functionality of our org, so I do not know how to really solve this issue considering I don't even know what could be problematic aside from long running callouts. Thanks!

1
  • although I realize this is not helpful, Every developer before me has written code with no regards to limits, so inefficient code can be anywhere reminds me of The Three Envelopes. N.B. A useful logging framework is from Andrew Fawcett that we use in our org - it can capture soql calls, cpu time, elapsed time, etc. that you can persist for later analysis
    – cropredy
    Mar 15, 2019 at 19:16

2 Answers 2

6

Your best bet is to enable Governor Limits Warnings. This will send you emails every time a transaction exceeds 50% of the governor limits, which should get you pretty close to nailing down where your problems are.

You can also engage support, which can check the logs to determine which of your requests are running the longest. This information should generally be enough to narrow down the possibilities.

A third option is to get your unit tests up to date, and run all your tests to see which tests are taking the longest. Even better, simulate callout times with spin loops of average API time, and assert that the governor limits are not above a certain threshold.

Also, if you're trying to get the concurrent limits to show up, try setting up more than just 11 calls at once. There's a bit of wiggle room. Make it more like 100 calls simultaneously logged in as multiple users. I know it'd be time consuming to set up, but I feel you could get some decent logs this way.

Lastly, you could always start optimizing your code. It sounds like you have a lot of technical debt, and now is the time to pay it down. Traditionally, I've found that most code can usually be optimized by at least 50% by an experienced developer. If you don't have any resources like this, you could outsource it to a consultant. This is probably the most expensive option, but might be your only choice if the other options don't pan out.

4
  • Thank you for the help. I do have "Send Apex Warning Emails" enabled and have since I arrived at this organization. If a transaction exceeds 5 seconds, would a warning email be sent? Because I only receive warning emails from when I run anonymous apex. I have had a suspicion since I got here the Apex error/warning emails have not functioned correctly as I do not receive them in many cases where I should. My org at my previous employer sent these emails reliably and often. Mar 18, 2019 at 17:51
  • @RyanWerner That's interesting. It certainly should work. You might want to open a case if you're not getting those messages.
    – sfdcfox
    Mar 18, 2019 at 18:04
  • Based on the way the "Set Up Governor Limit Email Warnings" page is worded, it sounds like you will only get an email if you invoke the Apex code that triggers the warning yourself. Any user could tip an org over the 50% mark on the concurrent transaction limit by performing an action that triggers Apex. Is there a way for an admin to receive all the notifications, regardless of which user initiated the transaction? Or is that how it actually works? Jun 10, 2019 at 17:53
  • 1
    @MatthewSouther The wording is incorrect. The configured user will receive notifications when any governor limits from any user reaches 50% or more. Feel free to try it out.
    – sfdcfox
    Jun 10, 2019 at 18:44
5

To add on sfdcfox's answer.

We also had faced this problem, It was mostly due to callouts that were taking too much time. 30secs plus. If few callouts like this are concurrently going on all other operations would then be failed.

1st Thing we did was to find which callouts are taking too much time, I added an architecture to Store starttime of request and at what time response was received. if it was more than 10 secs, create a record to log it. Is this their usual behaviour to consume more than 10 secs always. If yes then instead of using Request and Reply we used fire and forget mechanism and then use Platform events to notify user of the response.

Secondly, sometimes you want the callout to be synchronous eg callout from a VF page /lightning component. In that case you can convert it into a Continuation Async Callout which to end user looks like synchronous callout.

Even though Callouts are the main reason for this , sometimes it can be due to the use of unoptimized code and heavy SOQL which takes a big database time. If you are doing heavy lifting on the UI/API, it makes sense to move it to a future / queueable /batch if not needed immediately.

A challenge is to find which process / callout took too much time. You can raise a case with SF , they will provide the className and method and execution which was taking much time and you running into this concurrent condition.

5
  • 1
    +1 I could co-relate all these topics with the integration designer exam :)
    – Jayant Das
    Mar 15, 2019 at 16:36
  • @JayantDas now when you say, i kinda remember this was there in Integration arch and Data Arch exam. Mar 15, 2019 at 16:45
  • This is a great help, thank you! Mar 18, 2019 at 17:57
  • Recently we started facing this issue but looks like Http callout timings are not calculated in this anymore. Is it true? ` If more transactions are started while the 10 long-running transactions are still running, they’re denied. HTTP callout processing time isn’t included when calculating this limit.` Dec 15, 2021 at 4:37

You must log in to answer this question.

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