Large enrollment Workflows with custom code

Hey guys!

Have you guys ever run into secondly-rate-limit error when running a Custom code block in a workflow with large amount of enrollment?

This is because HubSpot don’t run the enrollment one by one as the setup would make you believe. All of the enrollment is push from different treads and run at the same time, thous why we are running into secondly-rate-limit errors.

Option Explored

  • Use time out function have throttle the limit some times, but it can become painfully slow when running large amount as well as when a code block takes over 20 second it will automatically retry later thous wasting progress, and if one enrollment will always take more than 20 second then it will create an infinte loop.
  • Reading RawHeader for the secondly-rate-limit is another option I have explored. It is a similar story to timeout function, still unclear about when in the code the process was forced to stop.

Propose changes

  • Have an Active Counter and list of enrollment inside each workflow to indicate the progress, It is a similar process to Object on hold. The active counter is already available in the WorkFlow API Get workflows | Workflows API (hubspot.com)
  • Lengthen 20 Second Action counter. If this can be done safely then I don’t see the downside, some complicated Codes will take a long time!

Any Ideas to for a workaround in the main time would be greatly appreciate!

Hi, @YZhou8 :waving_hand: Thanks for providing all those details! Hey, @LMeert @himanshurauthan @ChrisoKlepke, do you have any additional troubleshooting tips or suggesting for @YZhou8?

Thank you very much! — Jaycee

Hi Everyone,
I know this post is a bit older now, but I thought I’d add a solution for anyone that’s having similar issues.
The issue with using any HubSpot delays is that if all the objects are enrolled at the same time, for example when an import is done they will hit the delay stage at the same time, therefore they will all still hit your custom coded step at the same time, not resolving the limit issue.
What I suggest doing is an exponentially increasing randomised delay using setTimeout(). I’ve put an example of how this can be done below:

{

 let timeout = 5000;
 const maxTries = 5;
 let outcome = 0;
 let data;

 for (let i = 1; i <= maxTries; i++) {
 const response = await fetch(url, options);
 if (response.status === 200) {
 data = await response.json();
 outcome = 200;
 break;
 } else {
 console.log(`Attempt ${i} failed. Retrying in ${timeout}ms...`);
 await new Promise(resolve => setTimeout(resolve, timeout));
 timeout *= 3*Math.random();
 }
 }

 if (outcome !== 200) {
 throw new Error(`Max retries reached. Unable to fetch data.`);
 }

}

As you can see, everytime the response fails, it multiples the delay anywhere from 0-3 times and retries up to 5 times before erroring.
For the timing I would suggest finding out what you’re largest import/creation event would be and see what timeframe this would need to be split over to be within the rate limit.