SuiteScript does not offer a native way to pause the execution of your server-side script if you need to. While there are several ways to mimic a “sleep” action, the most reliable option is to use a delay service (or build your own).
When integrating NetSuite with other systems, you might encounter APIs that define a throttling limit. Throttling is a safeguard built into most APIs to limit the number of calls that you can make to a given endpoint in a specific amount of time. Throttling limits widely vary; some APIs will allow several calls per second while others might limit you to a few calls every minute.
Recently, I worked on an integration with an API that had a very high throttling limit of 1 call per minute for one of its endpoints! We knew up front that there would be business scenarios in which we would not meet this requirement. Therefore, we needed a reliable way to inject a delay between API calls. It turns out that NetSuite does not provide any clean means to implement server-side delays so we needed to look elsewhere.
Most of the solutions you’ll find out there are pretty much unreliable hacks which I do not recommend. Here are the most popular ones:
- Write a function like this one that idles away in a while loop until the desired amount of time elapses. This concept is known as busy-waiting or spinning in the software development world and is generally considered an anti-pattern that wastes useful processor time. Moreover, users have reported NetSuite throwing an SSS_INSTRUCTION_COUNT_EXCEEDED error when the delay exceeds 1 – 2 minutes. Avoid this approach.
- Perform a “slow” task in NetSuite, e.g., load a large file, run a complex (transaction) search with many rows, or call a SuiteScript API that is known to be slow. These are all variants of the same hack: Do something you don’t care about in the hope that sufficient time will elapse. This approach is unreliable as the time taken to execute your operation will vary (i.e. imprecise), NetSuite may silently optimize your search, etc. So you can never be sure you’ve waited long enough. Again, not an attractive solution.
setTimeout()will only work in client-side scripts as it has a dependency on the
windowobject. Similarly, all libraries which I tried at the time of writing, e.g., EasyTimer.js, produced an error due to a dependency that NetSuite’s SuiteScript environment does not support.
Let’s now consider a few viable solutions.
Batching is a process of combining multiple calls into one. While batching is not strictly a solution for dealing with throttling limits, it might enable you to avoid the problem altogether. So, before considering other solutions, be sure you’ve investigated and, where possible, batched your API calls as this is a good practice in any case.
Use Client-Side Delays
Use a Delay Service
If your delay must be executed on server-side, you’ll need to look elsewhere as NetSuite does not offer a solution. Gladly, there are various free, open-source implementations on Github that you can use, for example, Flash or Slowwly. Although these services are intended to mimic a slow server, you can also use them to produce a delay.External delay services are the most attractive way to achieve a server-side "sleep" in NetSuite. Use one out there or host yours. Click To Tweet
If you so desire, you can also spurn your own implementation and host it on Heroku, AWS, or wherever you want. The choice is yours though I personally do not fancy or recommend reinventing the wheel. So, if there’s a dependable service out there, I’d rather use it than create my own.
Speaking about dependability, the services referenced above do not provide any uptime guarantees and may be pulled offline without notice. That’s a risk that might be prohibitive depending on your use case.
Good news: While discussing this challenge some time back in the NetSuite Professionals Slack community, a member spontaneously and graciously offered to make their internal delay service available exclusively to the NetSuite community. We would like to thank Darren Hill from ExtendApps for this gesture! Since they use the solution internally, it comes with a higher degree of confidence than random services out there. To prevent abuse, I will not share the URL here. Feel free to contact Darren directly or reach out at stories[at]netsuite-insights.com if you’ll like to make use of this service.
Barring future support of server-side delays in NetSuite, using a delay service is our recommended solution for the delay challenge as it involves no hacks and offers the desired level of precision. Nevertheless, here are a few things to bear in mind:
- Some delay services include a redirection feature. The idea is that you can provide your actual API call payload to the service and, after the delay, it will make the call for you. From a security perspective, this is a no-go! Avoid passing your API calls through random 3rd party services as you might expose security keys to unwanted persons. Instead, make two separate calls from within your NetSuite script – One to your delay service, followed by your actual API call.
- Regardless of whether you build the delay service yourself or use one from someone else, it is a good idea to make the URL configurable via your app preferences or as a script parameter. In that way, if the delay service is down or needs replacement, you don’t have to go digging in your code.
- Even with your delay implementation in place, be sure your code includes error handling for throttling limit violations. Usually, the API documentation will include details of which HTTP code to expect if you violate throttling limits. Your error handling should be able to process that code if it is ever received.
- Consider just-in-time delays. Here’s what I mean by that: Remember my example where the API had a throttling limit of 1 call per minute? Based on the business process, we knew in advance that 70 – 80% of calls would be more than one minute apart so we won’t hit the throttling limit. So, instead of adding a delay to every call, and bearing an unnecessary overhead most of the time, we created an implementation that makes calls with no delays by default. Only if the API returns a throttling limit error code, would we “sleep” and then retry. In this way, we improve average process execution speed.
I hope this article has shed some light on your options when it comes to realizing delays in your NetSuite scripts.
Do you know any other approaches that we haven’t covered? Share it in the comments section or email us at stories[at]netsuite-insights.com