Skip to content

Google Sheets

Google Sheets Apps Script triggers explained

Triggers decide when Apps Script runs, and the wrong type runs too often, too late, or without permission. Choose the event and make runs repeatable.

Talha Ansari··5 min read

Key takeaways

  • Simple triggers run without extra authorisation but cannot call most external services.
  • Installable triggers run as their creator and can access authorised services.
  • onEdit fires on user edits, not formula recalculations or script writes.
  • Make scheduled jobs idempotent and guard against duplicate triggers.
On this page

Two families of trigger

A trigger subscribes a function to an event: a file opening, a cell edit, a form submission, or a clock reaching a set time. Simple triggers use reserved names such as onOpen and onEdit. They need no setup, run without an authorisation prompt, and are restricted to a small set of services.

Installable triggers are created in the editor or with ScriptApp. They run with the authorisation of the person who created them, can call Gmail, UrlFetch, and other services, and can be time-based. That extra power comes with a dependency: the trigger acts as its creator, so the account must retain access.

Simple and installable triggers compared
AspectSimple triggerInstallable trigger
CreationReserved function nameEditor menu or ScriptApp
AuthorisationLimited authorisation, no promptRuns as the creator after approval
ServicesCannot call services that need authorisationCan call authorised services
EventsonOpen, onEdit, onFormSubmitTime-driven, onChange, onEdit, form submit, calendar
Best useLight interface changes and simple checksScheduled work, external calls, production jobs

Read the event object

Handlers receive an event object. For an edit, e.range tells you where the change happened, e.value is the new value, e.oldValue is the previous value, and e.source is the spreadsheet. Use those properties instead of assuming the active sheet.

Guard the handler before doing work. Check the sheet name and the column, then exit if the edit is outside the input area: if (e.range.getSheet().getName() !== 'Inputs') return;. Without the guard, a formatting change or a paste in a report tab can trigger a full recalculation.

onEdit does not fire when a formula recalculates, when a script writes a value, or when data arrives through the API. A multi-cell paste gives a range, and e.value may be undefined, so read the range. Use onChange for structural events such as inserting a sheet, not for cell values.

Schedule work with time-driven triggers

Time-driven triggers run hourly, daily, weekly, or at a set time. They use the script project's time zone, which is not always the spreadsheet's. Set it explicitly; a report scheduled for 06:00 in the wrong zone is a report for the previous day.

Make the job idempotent. A daily summary should key on the reporting date, check whether the output already exists, and overwrite or skip rather than append. If the run is retried, the result should be the same. Store the last successful run date in PropertiesService and backfill from there when a run is missed.

Use LockService when a run can overlap the next one. A job that usually takes two minutes but occasionally takes twenty will eventually collide with its own schedule, and two writes to the same sheet produce duplicated rows.

Create triggers in code

A trigger created by hand is invisible in the source and easy to forget. Create it in a setup function so the configuration is reproducible: ScriptApp.newTrigger('dailySummary').timeBased().everyDays(1).atHour(6).create(). Record the function name and schedule in the README.

Running setup twice creates duplicate triggers, and duplicate triggers are the usual cause of doubled emails and repeated rows. List the project triggers, match on the handler name, and delete existing ones before creating a new one. A small setup function that reconciles the desired state is safer than manual clicks.

Installable triggers have daily quotas and run as their creator. A trigger owned by a departing employee stops or fails. Transfer ownership, recreate the triggers, and test one run.

Make failures visible

By default an unhandled error stops the function and leaves a red entry on the Executions page. Nobody watches that page. Wrap the body in try and catch, write a row to a Logs sheet with timestamp, job name, status, and message, and send an alert only when the same job fails repeatedly.

Log a row identifier and an error message, but not a full record that may contain personal data.

Test the failure path, not just the happy path. Revoke a permission, point the job at an empty range, and run it twice in a row. A trigger that works once and duplicates on retry is not ready.

Trigger review checklist

Use this list when a job changes owner or starts behaving oddly.

  • One handler per job, with a name that says what it does.
  • Sheet and column guards at the top of every edit handler.
  • Idempotent writes keyed on a date or record ID.
  • A lock around any run that can overlap.
  • An explicit project time zone and a documented schedule.
  • An error log and alert path that have been tested.
  • Duplicate triggers removed before setup.
  • Owner and quota headroom reviewed after staff changes.

Frequently asked questions

Why is my onEdit trigger not firing?+

Simple onEdit only runs on user edits and cannot call authorised services. If the change comes from a formula, a script, or the API, use an installable trigger or a time-driven job instead.

Why did my scheduled job run twice?+

Duplicate installable triggers are the usual cause. List the project triggers, remove the extra one, and make the job idempotent so a retry cannot duplicate its output.

Can a simple trigger send email?+

No. Simple triggers run with limited authorisation and cannot call Gmail. Use an installable trigger created by an account with the required access.

How do I test a trigger without waiting?+

Run the handler manually with a fabricated event object, then check the log. Test the real trigger once afterwards.

Need help applying this?

Improve your excel & google sheets.

Review the service scope or tell us what you are trying to improve. We will reply with a clear next step.

Free KPI definition template

Related reading