What is calendar sync?

By Rida F'kih · August 11, 2026 · Updated October 29, 2026

Calendar sync copies events from one calendar onto another and keeps those copies current as the originals change. Keeper.sh, a calendar sync service, does this between Google Calendar, Outlook, iCloud, Fastmail and any CalDAV server, writing each copy as a busy block. Sync has three steps: detect what changed at the source, write the change to the destination, and remove copies whose original no longer exists.

How sync differs from subscribing and sharing

Sync writes copies of events onto a calendar you own, subscribe reads a published calendar feed, and share gives another person access to your calendar. Only sync puts events onto a second calendar, so only sync blocks time there for people who check that calendar's availability.

MethodWhat happensEvents written onto your other calendarUpdates on its own
SyncA service reads one calendar and writes a copy of each event onto anotherYes, one copy per eventYes: with Keeper.sh, every 30 minutes on Free; on Pro, within seconds for Google and Outlook and every minute for iCloud, Fastmail and CalDAV (pricing)
SubscribeA calendar app reads a published .ics link and shows it as a separate read-only calendarNoYes, on the receiving app's schedule: about every 3 hours in Outlook.com (Microsoft); in Google Calendar, interval not published
ShareAnother person gets access to your calendar where it already isNoYes, because there is only one calendar
ImportAn .ics file is copied in onceYes, onceNo

A subscription refreshes late because the receiving app decides when to fetch the link; why a subscribed calendar falls behind covers that delay. Sharing leaves the events in one place, which sharing a Google Calendar walks through. Sync is the option for keeping work and personal calendars, or several work accounts, from double-booking.

How a sync tool notices a change

A sync tool notices changes by polling the source on a schedule, by receiving a push notification from the provider, or by asking for only what changed since a saved token. A sync tool can combine all three. Polling is simple and works everywhere, but a change waits until the next poll. Push notifications tell the tool that something changed without saying what; Google Calendar offers them through push notification channels, and Microsoft Graph through change notifications. The incremental token then answers what changed. Google returns a nextSyncToken that the tool sends back as syncToken to receive only the changes since the last read, as Google's guide to synchronizing resources efficiently describes. Microsoft Graph does the same with a delta query, replaying a saved deltaLink. Tokens expire, and both providers then answer with HTTP 410 Gone. When a token expires, the tool discards it, reads the whole calendar again and starts a new token.

Why CalDAV and ICS calendars are read in full

CalDAV and ICS calendars are usually read in full on each check, because a reliable incremental option is not available everywhere. A CalDAV client asks for every event in a time range with a calendar-query REPORT, and an ICS link is a file containing the whole calendar. RFC 6578 defines a sync-collection report with its own sync token, but server support is uneven and the report covers the whole collection rather than a date range, so a calendar with years of history returns far more than a sync tool needs. Reading the full window each time costs more requests, and an event missing from the response has been deleted. The deletion problems in the next section come from incremental reads, where a missing event says nothing.

Why deleted events are easy to miss

Deleted events are easy to miss because an incremental read reports only what changed, so a deletion has to arrive as an explicit marker that the sync tool must recognise. In a full listing, a deleted event is absent. In a delta, almost every event is absent from almost every response, so absence means nothing. Google Calendar includes deleted events in incremental results with status: "cancelled", and Microsoft Graph returns a tombstone object carrying an @removed annotation. A tool that skips either marker keeps the copy forever. Two further traps follow. A delta can contain the same event twice if it was edited while the tool was paging through results, so the tool has to keep the newest version rather than the last one it received. And a deletion that refers to a whole recurring series, rather than one occurrence, has to remove every copied occurrence of that series, or those copies are stranded on the destination with nothing left to delete them.

What stops two-way sync from looping

Two-way sync stops looping by marking every copied event so that each side can recognise copies and skip them when it reads. Without a marker, copying calendar A into calendar B and B back into A copies the event to B, copies that copy back to A, and keeps doubling on every pass. On Google Calendar and CalDAV, the marker can live in the event's UID: the tool writes a UID with a fixed suffix, and any event whose UID ends in that suffix is ignored as a source. Outlook does not allow this, because Microsoft Graph assigns the iCalUId itself when an event is created. There the marker moves to an Outlook category on each copied event. A category is visible and a person can remove it, so Keeper.sh treats an event without its marker as the person's own event and never deletes it. An unmarked copy is then left as a duplicate the person can delete. If you are seeing doubled events today, why the same event appears twice covers the common causes.

Repeating events, time zones and daylight saving

Repeating events break sync when the tool expands the series in absolute time instead of in the event's own time zone, or when it loses the exceptions attached to the series. RFC 5545 stores a repeating event as a main event with an RRULE, an EXDATE for each skipped date, and a separate event with a RECURRENCE-ID for each occurrence that was moved or edited. A weekly 09:00 meeting in Toronto stays at 09:00 local time when daylight saving starts, which is not a fixed number of hours after the previous week. A tool that adds seven days of milliseconds puts every later occurrence an hour off, so expansion has to happen on the wall clock of the event's time zone. The skipped dates and moved occurrences then have to be removed from or added back to the expansion. Writing each occurrence to the destination as a standalone event avoids reinterpreting edits to a series differently for each provider. Keeper.sh's repeating event changes entry shows how this looks when it works: a moved series moves its copies, and a skipped date removes only that occurrence.

All-day events

All-day events break sync when a tool confuses a date with a time, or misreads the end date. RFC 5545 marks an all-day event by giving DTSTART a DATE value instead of a DATE-TIME, and DTEND is exclusive, so a one-day event on the 5th ends on the 6th. Misreading that end date is the usual cause of all-day events that stretch across two days. Providers also signal all-day events differently: Google Calendar uses start.date instead of start.dateTime, Microsoft Graph sets an isAllDay flag, and iCalendar uses the value type. Some calendar links go further and publish a day off as a timed event running from midnight to midnight, which appears as a 24-hour block rather than a banner across the top of the day. Treating that shape as all-day is a guess, so it is best offered as a per-calendar choice, which is how Keeper.sh's midnight-to-midnight events setting works.

Why removing copies is the risky part

Removing copies is the riskiest part of calendar sync, because a tool that deletes on the strength of incomplete information can wipe out a whole calendar of copies. Copies have to be removed in two situations. The first is ordinary: the source event was deleted, so its copy goes too. The second is cleanup: a write can fail halfway, leaving a copy on the destination that the tool has no record of, and without a sweep for such orphans those copies stay forever. That sweep is where the danger lies. Run against a partly loaded or out-of-date view of the source, it decides that every copy is an orphan and removes them all. Keeper.sh therefore removes only events that carry its own marker, stops a run when a newer one has started for the same calendar, and records its progress after each batch of writes rather than at the end. Deleting something that is already gone counts as success, since the calendar ends up in the intended state either way.

How Keeper.sh handles calendar sync

Keeper.sh is a calendar sync service that copies events between Google Calendar, Outlook, iCloud, Fastmail and any CalDAV server. Each copy is a busy block named after the source calendar. The title, description and location are hidden by default, Pro can turn them back on per calendar, and guest lists are never copied. Each connection runs one way, so two-way sync is two connections; the calendar sync features page lists what else each connection can do. The Free plan covers 2 calendar accounts and 3 connections, with changes landing every 30 minutes. Pro is $5 a month or $45 a year, with Google and Outlook changes landing within seconds and iCloud, Fastmail and CalDAV changes landing every minute (pricing).

On a two-way pair, each side skips the copies the other one made. Step-by-step setups for the common pairs are in how to sync Google Calendar and Outlook, how to sync iCloud and Google Calendar and which Google Calendar sync method you need. For other ways to do this, the best calendar sync tools compared covers the commercial options, and open-source calendar servers and sync tools covers CalDAV servers such as Nextcloud and Radicale and the tools that sync them.

Common questions about calendar sync

What is the difference between syncing and subscribing to a calendar?

Syncing writes a copy of each event onto your other calendar and keeps it current. Subscribing shows a published calendar link as a separate read-only calendar that the receiving app refreshes on its own schedule, so its events never block time on your own calendar.

Does two-way calendar sync create duplicate events?

No, not when each copy is marked. Keeper.sh skips its own copies when it reads a calendar, so two connections running in opposite directions do not copy an event back and forth.

Why does a deleted event sometimes stay on the synced calendar?

An incremental read reports only what changed, so a deletion arrives as a marker: Google Calendar sends the event with status cancelled, and Microsoft Graph sends a tombstone with an @removed annotation. A sync tool that skips the marker keeps the copy.

Can Keeper.sh use cookies for analytics?