Apps Script tem teto

Como fazer o Apps Script continuar depois do teto de seis minutos: um script que processa as linhas de uma planilha em lotes, para antes de estourar o teto de tempo, guarda onde parou, agenda a própria volta e limpa tudo quando termina.

  • Apps Script
  • Google Planilhas
  • código de exemplo

Publicado em

Leia antes: o limite deste guia

As cotas e os limites do Apps Script mudam. A própria página do Google diz: "sujeitas a eliminação, redução ou alteração a qualquer momento, sem aviso prévio". Os números deste guia são os da página oficial em 10/11/2026; confira na página antes de depender deles. O código deste guia foi testado uma vez no Google Apps Script, em 10/11/2026, numa planilha de exemplo com 200 linhas e com o limite reduzido para dez segundos, para provocar a parada. O limite de cinco minutos do código e planilhas grandes não foram testados: o teste de verdade é seu. Rode primeiro numa planilha de teste, com dados de exemplo, nunca na planilha que você usa de verdade.

O que é cada coisa

  • Execução: cada vez que o script roda do começo ao fim (ou até ser interrompido). Segundo a página de limites do Google, o tempo de execução é de seis minutos por execução, tanto na conta pessoal quanto na Workspace.
  • O que acontece ao passar do limite: a página diz "If you exceed a quota or limitation, your script throws an exception and execution stops." A página não traz a mensagem exata do teto de seis minutos, por isso este guia não cita nenhuma.
  • Lote: um pedaço da planilha (no exemplo, vinte linhas) processado de uma vez, em vez de uma linha por vez.
  • Propriedades do script (PropertiesService): onde o script guarda dados simples em pares chave e valor. A página diz "Allows scripts to store simple data in key-value pairs". Aqui guardam a próxima linha a processar.
  • Gatilho de tempo: faz uma função rodar depois de um intervalo ou em um horário. Dá para criar e apagar por código ("Create and delete triggers programmatically with the Script service."). O método after(milissegundos) "Specifies the minimum duration (in milliseconds) after the current time that the trigger runs."
  • Outros limites da mesma página (conta pessoal e Workspace): destinatários de e-mail por dia, 100 e 1.500 (veja o aviso sobre contas de teste abaixo); tempo total de execução dos gatilhos por dia, 90 minutos e 6 horas; gatilhos por usuário por script, 20 nas duas.

Planilha de exemplo (dados inventados, EXEMPLO)

Use uma planilha nova, só para teste. Abra Extensões, Apps Script (o script fica ligado à planilha). Cole o código abaixo e rode a função criarDadosDeExemplo uma vez: ela cria a aba Exemplo com duzentas linhas, colunas item, valor e resultado, tudo inventado.

O código para copiar

Arquivo completo. Cole no editor do Apps Script no lugar do que estiver lá.

Código (cole no editor do Apps Script)
const NOME_ABA = 'Exemplo';
const TAMANHO_LOTE = 20;
const LIMITE_MS = 5 * 60 * 1000;
const CHAVE = 'proximaLinha';
const FUNCAO = 'processarEmLotes';

function criarDadosDeExemplo() {
  const planilha = SpreadsheetApp.getActiveSpreadsheet();
  const aba = planilha.getSheetByName(NOME_ABA) || planilha.insertSheet(NOME_ABA);
  aba.clear();
  const linhas = [['item', 'valor', 'resultado']];
  for (let i = 1; i <= 200; i++) {
    linhas.push(['Item ' + i, i, '']);
  }
  aba.getRange(1, 1, linhas.length, 3).setValues(linhas);
}

function apagarGatilhos() {
  ScriptApp.getProjectTriggers().forEach(function (gatilho) {
    if (gatilho.getHandlerFunction() === FUNCAO) {
      ScriptApp.deleteTrigger(gatilho);
    }
  });
}

function agendarContinuacao() {
  ScriptApp.newTrigger(FUNCAO).timeBased().after(60 * 1000).create();
}

function iniciar() {
  PropertiesService.getScriptProperties().deleteProperty(CHAVE);
  apagarGatilhos();
  processarEmLotes();
}

function processarEmLotes() {
  const inicio = Date.now();
  const propriedades = PropertiesService.getScriptProperties();
  const aba = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(NOME_ABA);
  const ultimaLinha = aba.getLastRow();
  let linha = Number(propriedades.getProperty(CHAVE)) || 2;

  apagarGatilhos();

  while (linha <= ultimaLinha) {
    if (Date.now() - inicio > LIMITE_MS) {
      agendarContinuacao();
      return;
    }
    const quantidade = Math.min(TAMANHO_LOTE, ultimaLinha - linha + 1);
    const valores = aba.getRange(linha, 2, quantidade, 1).getValues();
    const resultados = valores.map(function (celula) {
      return [celula[0] * 2];
    });
    aba.getRange(linha, 3, quantidade, 1).setValues(resultados);
    Utilities.sleep(2000);
    linha += quantidade;
    propriedades.setProperty(CHAVE, String(linha));
  }

  propriedades.deleteProperty(CHAVE);
}

Como testar

  1. Rode criarDadosDeExemplo. Autorize o script quando o Google pedir (é a sua própria planilha de teste).
  2. Para ver o gatilho funcionando sem esperar cinco minutos, troque a linha do limite por const LIMITE_MS = 10 * 1000; (dez segundos). O sleep de dois segundos por lote simula trabalho pesado.
  3. Rode a função iniciar. Ela zera o marcador, apaga gatilhos antigos desta função e processa até passar do limite. Depois de uns dez segundos, ela para e agenda a volta.
  4. Em Gatilhos (o ícone de relógio na barra lateral), deve aparecer um gatilho de tempo para processarEmLotes. Em Configurações do projeto, Propriedades do script, deve aparecer a chave proximaLinha com a próxima linha a processar.
  5. Espere cerca de um minuto, ou mais: o gatilho roda sozinho e continua de onde parou. Repita a conferência até a coluna resultado estar preenchida nas duzentas linhas.
  6. No fim, não deve sobrar gatilho para processarEmLotes nem a chave proximaLinha.
  7. Volte LIMITE_MS para 5 * 60 * 1000 (cinco minutos, uma margem de um minuto abaixo do teto de seis) e troque o cálculo do exemplo (valor vezes dois) pelo seu trabalho de verdade, ainda numa cópia.

Como o código funciona

  1. processarEmLotes anota a hora de início e lê a próxima linha guardada nas propriedades do script (se não houver, começa na segunda linha, logo abaixo do cabeçalho).
  2. Apaga gatilhos antigos da própria função, para não acumular.
  3. Processa um lote por vez e grava o resultado na planilha. Depois de cada lote, salva a próxima linha. Se o Google interromper de repente: como a escrita na planilha vem antes de salvar a propriedade, o lote em andamento pode ser repetido na próxima execução.
  4. Antes de cada lote, confere se já passou do limite. Se passou, agenda um gatilho de tempo para um minuto depois e termina limpo.
  5. Quando as linhas acabam, apaga a propriedade. Como o gatilho antigo é apagado no começo de cada execução, não sobra nenhum no fim.

Regra de bolso

Trabalho que pode passar de seis minutos nunca roda em uma execução só: divida em lotes, confira o relógio a cada lote, guarde onde parou e agende a volta. Pare com uma margem (no exemplo, um minuto) e não no último segundo.

Antes de levar para o seu projeto

  • Teste numa cópia da planilha, não no arquivo original.
  • O script do exemplo é ligado à planilha. Em script solto, troque SpreadsheetApp.getActiveSpreadsheet() por SpreadsheetApp.openById('ID_DA_PLANILHA') com o ID da sua planilha de teste.
  • Gatilhos instalados rodam na conta de quem os criou: "Installable triggers always run under the account of the person who created them."
  • O tempo total dos gatilhos conta por dia (90 minutos na conta pessoal e 6 horas na Workspace, segundo a página em 10/11/2026). Um trabalho muito grande pode bater nesse limite também.
  • Se o seu lote envia e-mail, a cota de destinatários por dia vale (100 na conta pessoal e 1.500 na Workspace, segundo a página). A página cita o método MailApp.getRemainingDailyQuota() para ver o que sobra. A página diz: "Limites adicionais são aplicados a contas de teste." Para contas de teste convertidas em assinatura, ela diz que os limites aumentam se o domínio tiver pago pelo menos USD 100 de forma cumulativa e depois de passarem pelo menos 60 dias desse mínimo. Veja o seu caso na página. A tabela também tem a linha "Destinatários de e-mail por dia no domínio": 100 na coluna de contas de consumidor e 2.000 na coluna Workspace, segundo a página em português.
  • Ler e gravar um lote inteiro de uma vez, como o código faz, costuma ser mais rápido que célula por célula. É cuidado geral de planilha, não tirado da página do Google.
  • Se um lote falhar no meio, o marcador ainda aponta para o início dele: confira se reprocessar as mesmas linhas não causa dano (por exemplo, e-mail enviado duas vezes). Depois de um erro, rodar processarEmLotes de novo continua da linha salva (use iniciar só para recomeçar do zero). Depois de um erro nenhum gatilho fica agendado, então a retomada é manual.
  • O código não usa LockService. Não rode a função à mão enquanto uma execução do gatilho estiver em andamento, para duas execuções não processarem as mesmas linhas.
  • O after() define o tempo mínimo até o gatilho rodar, não um horário exato.
  • O limite de cinco minutos é uma recomendação deste guia (margem de um minuto abaixo do teto), não um número da página.

Fontes

Páginas do Google for Developers abertas em 10/11/2026: Quotas for Google Services (inglês), Quotas for Google Services (português), Installable Triggers, ClockTriggerBuilder, PropertiesService e Properties.

Código: testado no Google Apps Script em 10/11/2026, numa planilha de exemplo com 200 linhas e com o limite reduzido para dez segundos: a execução parou no limite, guardou a próxima linha nas propriedades do script, o gatilho de tempo continuou sozinho e, no fim, não sobrou gatilho nem propriedade.

Fechamento do guia

Agora você sabe montar um script que processa a planilha em lotes, para antes do teto de seis minutos e continua sozinho de onde parou.

Seguir @drasdiegotech

Salve este guia nos favoritos do navegador e salve o reel no Instagram para voltar quando precisar.

Ver outros guias

Este site conta visitas com o Vercel Web Analytics, de forma anônima e agregada, sem cookies de terceiros. Aviso de privacidade