Разработка · 7 мин чтения

Лимиты Google Apps Script: триггеры, время выполнения и как в них уложиться

Скрипт на Google Apps Script, который в песочнице отрабатывает за 40 секунд, у клиента на боевых данных падает с ошибкой Exceeded maximum execution time - с этого обычно начинается настоящее знакомство с лимитами Google Apps Script. Официальной сводной таблицы у Google по сути нет: 6 минут на выполнение упоминаются в одном разделе документации, 20 000 вызовов UrlFetch в сутки - в другом, 20 триггеров на пользователя - в третьем. За несколько лет автоматизации Google Таблиц, форм на Tilda и статусов доставки СДЭК я упирался почти в каждый из этих потолков минимум один раз. Разберу, какие ограничения реально всплывают на практике, откуда они берутся и как спроектировать скрипт так, чтобы не переписывать его через месяц после запуска.

Какие лимиты Google Apps Script действуют на аккаунт

Первое, что стоит понять: набор квот зависит от типа аккаунта. У личного Gmail и у корпоративного Google Workspace лимиты Apps Script отличаются иногда в разы, и разработчик часто узнаёт об этом только когда скрипт, который отлично работал у него в тестовом аккаунте, начинает падать у клиента на обычной личной почте.

Параметр Обычный Gmail-аккаунт Google Workspace
Время выполнения скрипта 6 минут 30 минут
Runtime простых триггеров (onEdit, onOpen) 30 секунд 30 секунд
Runtime кастомных функций в Таблицах 30 секунд 30 секунд
Суммарное время работы триггеров в сутки 90 минут 6 часов
Триггеров на пользователя на один скрипт 20 20
Вызовов UrlFetch в сутки 20 000 20 000
Писем через MailApp в сутки 100 1 500

Цифры привожу по документации Google на момент публикации, но она периодически меняется без анонсов, поэтому если строите на лимитах критичную логику - закладывайте запас минимум в 20-30%, а не работайте впритык к паспортным значениям.

Лимит времени выполнения: 6 минут - это меньше, чем кажется

На бумаге 6 минут звучат достаточно, пока не начинаешь гонять цикл по нескольким тысячам строк Google Таблицы с обращением к внешнему API на каждой итерации. Условная задача - подтянуть статус заказа из личного кабинета СДЭК для 3000 строк с интервалом между запросами хотя бы в 200 мс ради устойчивости - сама по себе съедает больше 10 минут, и скрипт падает по таймауту на середине, оставляя часть строк обновлёнными, а часть нет.

Приём, который реально работает на практике: не пытаться обработать весь массив за один запуск. Скрипт сохраняет индекс последней обработанной строки в PropertiesService, обрабатывает порцию за 4-5 минут с запасом до лимита, а перед завершением сам ставит себе одноразовый триггер на следующий запуск через ScriptApp.newTrigger(…).timeAfter(60000). Получается конвейер из коротких запусков вместо одного длинного, который никогда не упрётся в потолок.

Отдельно стоит помнить про простые триггеры - onEdit и onOpen: у них лимит жёстче, 30 секунд, и он не увеличивается на Workspace. Если в обработчике onEdit висит тяжёлая логика с внешними запросами, она обязана либо укладываться в эти секунды, либо передавать работу дальше через собственный триггер с более щедрым лимитом.

Сколько триггеров можно повесить на скрипт

20 триггеров на пользователя на один скрипт - лимит одинаковый что для личного аккаунта, что для Workspace, и в него легко упереться на проекте, где на разные листы одной Таблицы навешаны отдельные onEdit, плюс несколько time-driven триггеров для разных участков автоматизации, плюс триггеры для отправки отчётов. При добавлении новой функции я сначала смотрю список действующих триггеров через File → Project Triggers, а не добавляю новый вслепую - иначе рано или поздно ловишь ошибку This trigger is not available anymore, и часть автоматизации молча перестаёт работать.

Второй потолок, который менее заметен - суммарное время работы всех триггеров в сутки: 90 минут для обычного аккаунта и 6 часов для Workspace. Если несколько time-driven триггеров запускаются каждую минуту и каждый работает по 2-3 минуты, бюджет выгорает за первые несколько часов дня, а остальные запуски просто не происходят без явной ошибки в логах - скрипт как будто засыпает без объяснений.

Для сравнения: бот на aiogram, который крутится на своём VPS, такими квотами вообще не связан - процесс на сервере обрабатывает обновления Telegram столько раз в секунду, сколько выдержит железо, и никакого дневного бюджета минут у него нет. Это одна из причин, почему для высокочастотной логики я стараюсь не тянуть её в Apps Script, а выносить на отдельный сервер.

Бесплатный материал

🎁 Полезный скрипт в подарок

Подпишитесь на Telegram - пришлю готовый скрипт по этой теме.

Без спама. Отписка в 1 клик.

Квоты на сервисы, которые ловишь незаметно

Помимо времени выполнения и триггеров, у каждого встроенного сервиса Apps Script свой потолок, и часть из них выясняется только в проде.

  • UrlFetchApp ограничен 20 000 вызовами в сутки и 50 МБ на один ответ. Звучит много, пока не начинаешь синхронизировать статусы заказов с СДЭК или подтягивать данные из WooCommerce каждые пять минут для сотен позиций - при неудачном ретрае без задержки квота выгорает за несколько часов, а не за сутки.
  • MailApp и GmailApp дают 100 писем в сутки на личном аккаунте и 1500 на Workspace - этого достаточно для уведомлений админу, но не для рассылки клиентам по каждому заказу с Tilda-формы: там нужен отдельный сервис отправки, а не Apps Script в роли почтового шлюза.
  • PropertiesService хранит суммарно 500 КБ и не больше 9 КБ на одно значение - удобно для флагов и индексов обработки, но не для кэша больших ответов API. Для них логичнее CacheService с TTL до 6 часов.
  • Отдельная головная боль - ошибка Service invoked too many times in a short time при частых обращениях к SpreadsheetApp. Она возникает не от превышения суточной квоты, а от слишком частых вызовов подряд, поэтому цикл из тысяч setValue() по одной ячейке нужно заменять на один getRange().setValues() с двумерным массивом.

Как проектировать скрипт, чтобы не упираться в лимиты

Из практики по десяткам интеграций с Google Таблицами и Tilda-скриптами вывел для себя правила, которые снимают большинство проблем с лимитами Apps Script ещё на этапе архитектуры:

  • Разбивать длинные обработки на порции с сохранением состояния в PropertiesService и продолжением через ScriptApp.newTrigger, а не пытаться закрыть весь массив данных за один запуск.
  • Ставить LockService.getScriptLock() на любой обработчик, который может сработать параллельно - иначе два одновременных триггера начинают писать в одну Таблицу и портят друг другу данные, а заодно быстрее выжигают квоту.
  • Кэшировать повторяющиеся внешние запросы через CacheService вместо того, чтобы дёргать один и тот же метод СДЭК или платёжного API на каждой итерации цикла.
  • Делать экспоненциальный backoff при ошибках UrlFetch вместо мгновенного повтора - иначе одна нестабильная интеграция сжигает суточный лимит вызовов за час.
  • Работать с диапазонами Таблиц батчами: одна операция getValues/setValues на весь массив вместо цикла с обращением к ячейке за ячейкой.

Часть этой логики - батчинг, ретраи с задержкой, работу с PropertiesService - проще не писать заново на каждом проекте: в библиотеке готовых скриптов для Google Таблиц у меня уже собраны рабочие заготовки под типовые задачи с учётом лимитов, о которых идёт речь в статье.

Когда лимиты Apps Script - сигнал переезжать на другую платформу

Если задача регулярно упирается в 6 минут, требует более частого запуска, чем раз в минуту, или должна стабильно принимать вебхуки без задержек на холодный старт - это повод не бороться дальше с квотами, а вынести логику за пределы Apps Script.

Критерий Google Apps Script n8n (self-hosted) Python-скрипт на VPS
Лимит времени на один запуск 6-30 минут не ограничен платформой не ограничен
Дневной бюджет времени триггеров 90 минут / 6 часов нет нет
Стоимость хостинга бесплатно в рамках Google-аккаунта от аренды сервера от аренды сервера
Гибкость интеграций с CRM и эквайрингом ограничена встроенными сервисами широкая, через ноды и HTTP максимальная, любой SDK

Для интеграции T‑Bank или другого эквайринга с WooCommerce, для приёма вебхуков с большим потоком заказов или для обработки статусов СДЭК в реальном времени я обычно сразу закладываю n8n или отдельный Python-сервис вместо Apps Script - так же, как aiogram-бот логичнее держать на своём сервере, а не пытаться эмулировать его через триггеры Таблиц. Apps Script отлично закрывает автоматизацию внутри Google-экосистемы, но не задумывался как замена полноценному бэкенду.

Связка сервисов без программистов

Автоматизация / n8n

от 25 000 ₽

Подробнее →

Частые вопросы

Что произойдёт, если скрипт Apps Script превысит лимит времени выполнения?

Выполнение прерывается с ошибкой Exceeded maximum execution time, и ничего не откатывается автоматически. Если скрипт писал в Таблицу построчно, часть строк успеет обновиться, часть нет - поэтому важно проектировать обработку с чекпоинтами и делать её идемпотентной, чтобы повторный запуск не портил уже обработанные данные.

Можно ли увеличить лимиты Google Apps Script, купив Google Workspace?

Часть квот действительно растёт - время выполнения скрипта увеличивается с 6 до 30 минут, суточный бюджет времени триггеров с 90 минут до 6 часов, лимит писем с 100 до 1500 в сутки. Но не все ограничения снимаются: 20 триггеров на пользователя на скрипт и 30-секундный лимит простых триггеров одинаковы для любого типа аккаунта, и купить их расширение отдельно нельзя.

Как понять, что скрипт скоро упрётся в квоту?

Смотрю журнал выполнений в Apps Script Dashboard - там видно фактическое время каждого запуска и причины ошибок. Отдельно веду счётчик обращений к UrlFetch в PropertiesService, чтобы не гадать по факту падения, а видеть приближение к суточному лимиту заранее.

Стоит ли использовать Apps Script для интеграции с СДЭК или платёжными системами вроде T‑Bank?

Для периодической проверки статусов или несложных уведомлений - да, это быстрый и дешёвый вариант. Для приёма вебхуков с ощутимым потоком заказов или для комплексной связки CRM, эквайринга и доставки лимиты Apps Script и задержки холодного старта веб-приложения становятся узким местом, и логичнее выносить эту часть на отдельный сервис.

Есть задача?

Обсудим в мессенджере

Расскажите, что нужно сделать — отвечу в течение 4 часов в рабочее время. Первая консультация бесплатно.

Самозанятый Калинкин Н. А. · работаю с физлицами и юрлицами

Продолжая пользование настоящим сайтом Вы выражаете своё согласие на обработку Ваших персональных данных (файлов куки) с использованием Yandex.Metrika.
Понятно