Deleting a time-driven trigger to "turn off" a nightly job feels clean until Monday when nobody remembers the exact hour, timezone, or handler name. A PAUSED Script Property keeps the trigger; the handler logs one line and returns. Flip the flag when you're done debugging.
TL;DR
- Keep the installable time-driven trigger in place.
- Gate the top of the handler with
isPaused()reading Script Properties. - When paused:
console.log/ toast once, return before UrlFetch or writes. - Menu Pause nightly / Resume nightly so you don't dig in the trigger UI at 11pm.
- This is not Dry Run (preview writes) and not "delete triggers by handler" — it's an ops kill switch.
Using the Apps Script editor a lot? NitroGAS drops free themes & snippets right into script.google.com — optional Co-Pilot when you want a boost.
Why not delete the trigger?
Triggers are easy to recreate wrong: wrong timezone, wrong interval, duplicate handlers after a copy. Script Properties survive deploys of the same project and make pause/resume a one-click story for whoever owns the sheet.
function isPaused() {
var v = PropertiesService.getScriptProperties().getProperty('PAUSED');
return String(v).toLowerCase() === 'true' || v === '1';
}
function setPaused(paused) {
PropertiesService.getScriptProperties().setProperty(
'PAUSED',
paused ? 'true' : 'false'
);
}
function menuPauseNightly() {
setPaused(true);
SpreadsheetApp.getActiveSpreadsheet().toast('Nightly PAUSED', 'Bootstrap', 5);
}
function menuResumeNightly() {
setPaused(false);
SpreadsheetApp.getActiveSpreadsheet().toast('Nightly RUNNING', 'Bootstrap', 5);
}
How should the nightly handler look?
Put the gate first — before locks, fetches, or sheet reads that cost quota:
function nightlySync() {
if (isPaused()) {
console.log('nightlySync skipped: PAUSED=true');
return;
}
// ... real work: UrlFetch, setValues, advance watermark
}
Optional: email yourself when a run was skipped for N consecutive nights so pause doesn't become permanent silence.
Pause vs Dry Run vs delete-triggers
| Goal | Pattern |
|---|---|
| Stop all side effects but keep schedule | PAUSED flag (this guide) |
| Rehearse an import with previews, no writes | Dry Run switch |
| Remove stray / duplicate triggers | deleteTriggersByHandler |
Menu wiring
function onOpen() {
SpreadsheetApp.getUi()
.createMenu('Bootstrap')
.addItem('Pause nightly', 'menuPauseNightly')
.addItem('Resume nightly', 'menuResumeNightly')
.addToUi();
}
Wrap-up
Pause should be boring: one property, one early return, one menu. When you're ready to go live again, resume — the trigger was never the problem.
NitroGAS has Script Properties and trigger helpers if you want the building blocks in the editor; Co-Pilot is optional when you're adapting this to a messier multi-job project. Happy Coding.


