Skip to content
// Calendar · Apps Script

Delete events in a date range in Google Calendar.

How to bulk-delete Google Calendar events between two dates using Apps Script, including the Utilities.sleep call that keeps you under the short-term quota.

I need to delete a batch of calendar events that fall between two specific dates without clicking through each one manually.

The script

copy · paste · trigger
deleteEventsInRange.gs
Apps Script
// Delete all events between startDate and endDate on the default calendar.
// Run from the Apps Script editor; authorize Calendar scope on first run.
function deleteEventsInRange() {
  var calendarId = 'primary';
  var startDate = new Date('2024-03-01T00:00:00');
  var endDate   = new Date('2024-03-31T23:59:59');

  var cal    = CalendarApp.getCalendarById(calendarId);
  var events = cal.getEvents(startDate, endDate);

  for (var i = 0; i < events.length; i++) {
    events[i].deleteEvent();
    Utilities.sleep(300);
  }

  Logger.log('Deleted ' + events.length + ' events.');
}

Need a variant? Gnaw writes a custom version from one sentence — fields, triggers, edge cases handled.

Walkthrough

How getEvents works (and what it actually returns)

CalendarApp.getCalendarById('primary') gives you the signed-in user's default calendar. Pass any calendar ID from your Calendar settings for a secondary calendar. getEvents(startDate, endDate) returns every event whose start time falls within that window, up to Google's undocumented hard limit of 2,500 events per call.

Both Date objects are constructed from ISO strings, which sidesteps timezone ambiguity better than passing year/month/day integers. Set startDate to T00:00:00 and endDate to T23:59:59 on the last day you want cleared, or events that begin at midnight on the boundary day will be missed.

The returned array is flat: each item is a CalendarEvent object. Recurring event instances come back as individual items, so deleteEvent() on each one deletes only that occurrence, not the series. To nuke the whole series you would need deleteEventSeries() — a different method entirely.

Why the sleep is not optional

The first time I hit 'Exception: Service using too many calendar operations for this user' I was deleting roughly 80 events with no pause. Apps Script enforces a short-term quota (around 50 calendar write operations per minute for consumer accounts; G Workspace accounts get more headroom but still have a ceiling). A tight loop blows through that ceiling in seconds.

Utilities.sleep(300) pauses 300 milliseconds between each deleteEvent call. At that rate you can delete about 200 events per minute, which keeps most accounts comfortably below the per-minute cap. If you're clearing thousands of events, increase the delay to 500 ms or batch the deletions across multiple script runs.

There is no batch delete in the CalendarApp API. Every event requires its own deleteEvent() call, so the sleep is the only lever you have.

Running it and handling the authorization prompt

Open script.google.com, create a new project, paste the function, and click Run. The first execution triggers an OAuth consent screen asking for 'See, edit, share, and permanently delete all the calendars you can access.' That broad scope is what Google requires for CalendarApp write operations; there is no narrower scope that covers deleteEvent.

After authorization, check View > Logs (or the Executions panel) to confirm the count. Logger.log prints 'Deleted N events' at the end, which is the only confirmation you get. There is no undo for deleted calendar events, so run the script against a narrow date range first to verify you are targeting the right calendar and window before widening the range.

If the script times out (Apps Script enforces a 6-minute execution limit), split the date range into smaller chunks and run each chunk separately. A month at a time is safe for most calendars.

Want a custom version?

Describe your sheet and the rule you want. Gnaw writes the Apps Script — fields, triggers, edge cases — in one shot.

FAQ

4 questions
Why does my script throw 'Service using too many calendar operations'?
You are deleting events in a tight loop without any pause. Add Utilities.sleep(300) after each deleteEvent() call. Consumer accounts are capped at roughly 50 calendar writes per minute; the sleep keeps you below that.
How do I delete events from a calendar other than my primary one?
Replace 'primary' with the calendar's full ID, which looks like an email address (e.g. '[email protected]'). Find it under Calendar Settings > Integrate calendar > Calendar ID.
Will deleteEvent() remove a recurring event entirely, or just one instance?
Just the one instance. getEvents() returns each occurrence as a separate CalendarEvent, and deleteEvent() on it removes only that date. To delete the whole series call deleteEventSeries() instead, but that removes every past and future occurrence.
The script times out before finishing. What do I do?
Apps Script cuts off after 6 minutes. Narrow the date range to one or two weeks per run, or add a counter that stops at, say, 200 deletions and re-run until the range is clear.
// one good script a week

Get a working Apps Script snippet in your inbox, weekly.