An easy way to deal with Google Apps Script’s 6-minute limit

About the 6-minute limit

Google Apps Script is handy, and it will help you a lot in your work. However, as you use it, you may hit a big wall. That is the six-minute limit on execution time. As the official documentation states, the maximum allowed time per execution of Google Apps Script is 6 minutes. ( As far as I can tell from the official documentation, there is no difference between paid users and free users. )

If the script execution time reaches 6 minutes, the script will stop suddenly, and an error message “Exceeded maximum execution time” will be displayed.

You will see an error message like this. πŸ˜₯

The processing speed of Apps Script is not that fast, so if you are loading data from Google Sheets or Google Drive, you will reach the time limit in no time. Then, what should we do? I will tell you how to solve this.

How to solve this?

This problem can be solved with Script properties and Time-driven triggers. You can use these mechanisms to rerun the Script as many times as you need.

Class PropertiesService allows you to store simple data in key-value pairs scoped to one script. So you can store the number of times your function has processed as the script’s property.

Time-driven triggers let scripts execute at a particular time. So you can set a trigger to run the function next time before the 6-minute limit is reached.

The mechanisms for overcoming the six-minute limit

However, when it comes to actually do it, you’ll find that it’s not easyπŸ˜“. You can find a lot of solutions that use this mechanism on the Internet. But you’ll soon understand that you have to do many things to use it; you will have to remove triggers and properties that are no longer needed, and you should determine how to pass arguments, and there are many other things.

So I created a Javascript class named LongRun to efficiently deal with the 6-minute time limit. It was created as an extension of my open-source project GAS-Terminal.

The LongRun class

This class hides operations such as PropertiesService and Time-based Triggers behind it, making it easy to perform long-running scripts. Here’s an example code.

function LongRunTest(
    // there must be no arguments, because the parameters must be retrieved from LongRun class.
    /* times: number, funcExecutionSeconds: number, maxExecutionSeconds: number, triggerDelayMinutes: number */
  ) {
  let longRun = LongRun.instance;

  // funcName must equal this function's name.
  const funcName = 'LongRunTest';

  // you can get the parameters from LongRun class.
  // the order of the array is the same as the order of the command definition.
  const params = longRun.getParameters(funcName);
  const times = parseInt(params[0]);
  const funcExecutionSeconds = parseInt(params[1]);
  const maxExecutionSeconds = parseInt(params[2]);
  const triggerDelayMinutes = parseInt(params[3]);

  // you can set the long-running configurations. of course you can use the default values.
  longRun.setMaxExecutionSeconds(maxExecutionSeconds); // default is 240 seconds
  longRun.setTriggerDelayMinutes(triggerDelayMinutes); // default is 1 minute

  // you should get the index to resume(zero for the first time)
  let startIndex = longRun.startOrResume(funcName);
  if( startIndex === 0 ){
    LogUtils.i('--- LongRunTest command started. ---');
  }

  try {
    // Execute the iterative process.
    for (let i = startIndex; i < times; i++) {
      LogUtils.i('Processing: ' + i);

      // Each time before executing a process, you need to check if it should be stopped or not.
      if (longRun.checkShouldSuspend(funcName, i)) {
        // if checkShouldSuspend() returns true, the next trigger has been set
        // and you should get out of the loop.
        LogUtils.i('*** The process has been suspended. ***');
        break;
      }

      // *** code your main process here! ***
      Utilities.sleep(funcExecutionSeconds * 1000); // demonstrate the process

      LogUtils.i('Processing Done!: ' + i);
    }
  }
  catch (e) {
    LogUtils.ex(e);
  }
  finally {
    // you must always call end() to reset the long-running variables if there is no next trigger.
    const finished = longRun.end(funcName);
    if( finished ){
      LogUtils.i('--- LongRunTest command finished. ---');
    }
  }
}

You can get the source code of the LongRun class from my GitHub repository. Please, check it! Of course, you can use the class solely, but it is more effective when used in conjunction with the GAS-Terminal framework.

Conclusion

The 6-minute limit problem is painful but can be solved by using the mechanism provided. And there are also some useful classes, such as the LongRun class. Let’s make use of Google Apps Script for long-time processing!πŸ‘

2 thoughts on “An easy way to deal with Google Apps Script’s 6-minute limit

  1. Hi! I’m currently doing a project which involves massive data communication between the google sheets and scripts, thus breaching the 6-minute rule. I’m a beginner in app script. My question is: how do I import longrun class from your GAS-terminal? I’m seeing the .ts are interconnected to each other. Which files only pertain to LongRun?

    Like

    1. Thanks! You are right.
      Sorry, there is less information about that, because I mainly think of it as a part of GAS-Terminal.
      In LongRun.ts, if you look at the import statement at the top of the file, you’ll see that it only uses StringUtils.ts.
      (I updated the LongRun.ts now because it had another unnecessary import statement(LogUtils.ts), sorry.πŸ˜“)
      So please take the two .ts files, and place them together where you want.😊

      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

Create your website with WordPress.com
Get started
%d bloggers like this: