← Calendar Autopilot · Guides
How to sync Google Sheets™ to Google Calendar™ automatically
Updated October 25, 2026
Lots of schedules live in a spreadsheet first: appointments, classes, shifts, deadlines, bookings. Getting them onto Google Calendar™ once is easy. Keeping the calendar right after you change, sort or delete rows in Google Sheets™ is the hard part. Here are the three real options, starting with the ones that cost nothing.
First, decide what "sync" has to mean for you
Write down which of these you need before picking a method. Most frustration comes from a method that does the first one and not the rest.
- Add: new rows become new events.
- Update: changing a row's date, time or title changes its event instead of making a second one.
- Delete: removing a row removes its event.
- Automatic: it happens without you clicking anything, even with the sheet closed.
- Two-way: moving an event in Calendar changes the row.
Option 1: import a CSV file (add only, one time)
Google Calendar can import a CSV file with columns named Subject, Start Date, Start Time, End Date, End Time, All Day Event, Description, Location and Private. Only Subject and Start Date are required, and the headers must be in English. You download the sheet as a CSV (File, then Download) and import it in Calendar under Settings, then Import & Export. Google's steps are on its import help page. Format dates like Google's example (05/30/2020) and times like 10:00 AM before you download.
The catch is in Google's own words: imported events "don't stay in sync." Import the same file twice and you get every event twice. Good for a one-off, not for a schedule that changes.
Option 2: a small Apps Script™ with a timer (free, add and maybe more)
Every Google Sheet has a script editor under Extensions, then Apps Script. Google Apps Script™ can create calendar events with CalendarApp. This example assumes column A is the title, B the start (a real date and time), C the end, and D is left empty for the script to fill with each event's ID:
function addNewRows() {
var cal = CalendarApp.getDefaultCalendar();
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet1');
var rows = sheet.getDataRange().getValues();
for (var i = 1; i < rows.length; i++) {
var title = rows[i][0], start = rows[i][1], end = rows[i][2], id = rows[i][3];
if (!title || !(start instanceof Date) || id) continue; // skip blanks, text dates, done rows
if (!(end instanceof Date)) end = new Date(start.getTime() + 60 * 60 * 1000);
var ev = cal.createEvent(title, start, end);
sheet.getRange(i + 1, 4).setValue(ev.getId()); // remember it, so no duplicates
}
}
To make it run on its own, click Triggers in the editor's left panel, then Add Trigger, pick addNewRows, choose a time-driven trigger and an hourly timer, and save. Google's trigger guide covers the details.
Know the limits before you rely on it:
- This version only adds. Change a row's time and the event stays where it was; delete a row and the event stays. Handling updates and deletes means looking up each saved ID and comparing, which is where most home-made scripts get complicated.
- Google's quota page lists 5,000 calendar events created per day for a personal account (10,000 for Google Workspace), 90 minutes of trigger run time per day for a personal account (6 hours for Workspace), and 6 minutes per run.
- Google notes that a time-driven trigger's exact time "might be slightly randomized," and that when a triggered run fails, "no error message appears on your screen." You get a summary email for your own scripts, so watch your inbox. To check by hand, open the editor and click Executions on the left.
- Date cells that hold text (for example, a pasted "Nov 3" that Sheets didn't recognize) aren't
Datevalues, so the script skips them. That's on purpose: a wrong guess is worse than a skipped row.
Option 3: an add-on that tracks every row
If you need updates, deletes and an automatic run you don't have to babysit, an add-on saves you writing and maintaining the comparison logic. Whatever you pick, check these things on its listing and in a test sheet:
- Change a row's time after the first sync. Does the event move, or do you get a second one?
- Sort the sheet and sync again. Still one event per row?
- Delete a row. Does the event go?
- Does it run with the sheet closed, and how often?
- What tells you if it stops running?
A quick checklist for any method
- Set the spreadsheet's time zone under File, then Settings (Google's steps) to where the events happen.
- Make sure date cells are real dates, not text.
=ISNUMBER(B2)returns TRUE for a real date, because Sheets counts dates as days since December 30, 1899. - Test with two or three rows on a spare calendar before you send a whole year to your main one.
Calendar Autopilot is the add-on we make for option 3. Each row is tied to its own event through a hidden ID column, so editing, sorting or copying rows still gives one event per row, and deleting a row removes its event. Automatic sync runs right after each edit plus an hourly check that works with the sheet closed, and if it ever stops checking in, it emails you.
Keep your calendar in step with your sheet
Calendar Autopilot shows ✓ on every row that's on your calendar, or ⚠ with the reason when one isn't, and lets you preview and undo syncs. Syncing by hand is free on any sheet, and automatic sync is free on 1 sheet (first 100 rows). Paid plans start at $3 a month. Install from Google Workspace Marketplace™ · Learn about Calendar Autopilot.
Google Sheets™, Google Calendar™, Google Apps Script™ and Google Workspace Marketplace™ are trademarks of Google LLC. Calendar Autopilot is made by Coding Friend LLC and is not affiliated with or endorsed by Google.