Exchange calendar sync with Google Calendar: what the server allows

Anyone asked to get an Exchange calendar and a Google Calendar to agree with each other usually discovers there is no single switch for it. There are three separate mechanisms, they sit at different layers of the stack, and only one of them is sanctioned by both vendors. The one that is sanctioned moves the least data. The ones that move the most data are either read only or run as a program on a desktop that has to stay awake. Picking the wrong one is how a calendar ends up with duplicated meetings, stale times, and events that show as busy with no title.

This is the shape of the problem and where each route stops.

Three different things get called sync

The word sync hides at least three behaviours, and support threads mix them freely.

Availability lookup means neither calendar stores the other's events. When a time is checked, one server asks the other server whether a person is busy, and gets back blocks of busy time. Nothing is copied. Nothing can go stale, because nothing is stored. The cost is that busy is all that comes back.

Feed subscription means one calendar holds a read only copy of the other. An iCalendar file is published at a URL, the second calendar fetches that URL on a schedule, and shows whatever it found. Events appear with their real titles. They cannot be edited on the subscribing side, and they are only as fresh as the last fetch.

Item level replication means a program reads events out of one calendar and writes matching events into the other, then keeps comparing the two and pushing differences. This is the only route where an event created on either side can end up editable on both. It is also the only route where a bug produces two copies of a meeting instead of one missing one.

Most of the frustration in this area comes from expecting behaviour from the first category while using the third, or the reverse. A person who wants colleagues to stop double booking a meeting room needs availability lookup. A person who wants the actual agenda of a work meeting visible on a phone needs replication or at least a feed. These are not the same requirement and they do not have the same answer.

Calendar Interop is the supported route, and it stops at availability

Google Workspace ships an administrator feature called Calendar Interop for exactly this pairing. It is the only route where both Google and Microsoft are in the supported path, and it belongs to the first category above.

Google's administrator documentation is specific about the ceiling:

Both availability and additional event information lookups are supported. For availability, only busy blocks are visible to users. For additional event information, only titles and locations of events are visible to users. Source: knowledge.workspace.google.com

So titles and locations can cross, if additional event information lookup is enabled. Descriptions, attachments, attendee lists, and conferencing details do not. Event level privacy is also honoured in both directions: an event marked private in Exchange does not expose its details to Google Calendar, and an event marked private in Google Calendar does not expose its details to Exchange.

The setup is domain level, not user level. A single person cannot turn this on for a personal Google account. The published requirements are Microsoft Exchange 2016 or Exchange Online as part of Microsoft 365, inbound and outbound internet access to Exchange Web Services, an SSL certificate on the Exchange server issued by a trusted public root certificate authority, and a role account on each side so each system can query the other. Authentication differs by deployment: Calendar Interop supports Basic authentication for on premises Exchange and OAuth 2.0 for Exchange Online, which matters because Microsoft has been retiring Basic authentication for Exchange Web Services.

What the route does buy is a working scheduling assistant across both systems. Free time can be found for a mixed group from either side, and meeting rooms held in one system can be booked from the other. For an organisation whose actual complaint is failed room bookings and double booked people, this is the correct answer and the other two routes are a detour.

The iCalendar URL route is read only, and slower than it looks

The second route uses the iCalendar format described in RFC 5545. One calendar publishes a URL, the other subscribes to it. It needs no administrator, which is why it is the route most individuals reach for.

The trap is refresh interval. Microsoft's own documentation on subscribing to a calendar in Outlook.com and Outlook on the web puts a number on it:

When you subscribe to a calendar, your calendar will automatically refresh if the other calendar is updated. This can sometimes take more than 24 hours. Source: support.microsoft.com

The same page states that updates should happen approximately every three hours, with more than 24 hours as the outer bound. For a calendar of school terms or public holidays that is fine. For a calendar where a meeting gets moved an hour earlier at 9am, it is not. A room can be double booked inside that window and neither side will show a conflict.

There is a second trap in the same dialog. Uploading an .ics file and subscribing to an .ics URL look almost identical in the interface and behave completely differently. Microsoft's documentation is blunt about the difference: an imported file is a snapshot of the events at the time of import, and the calendar does not refresh imported events even when the owner makes an update. A person who imports once, sees the right events, and assumes it will stay current has built a calendar that silently drifts from the day it was created.

The read only property is worth stating plainly too. Subscribed events cannot be edited, moved, or deleted from the subscribing calendar. Apple's Calendar documentation makes the same point about subscribed calendars on macOS and recommends sharing rather than subscribing when more than one person needs to edit. That advice generalises: if the goal is editing, the feed route is the wrong layer.

Two way sync means a separate program copying items

The third route is a program that holds credentials for both calendars and reconciles them. The long running open source option for this pairing is Outlook Google Calendar Sync, usually shortened to OGCS. Its own site describes the scope: one way in either direction or two way, covering subject, description, location, attendees including whether they are required or optional, reminders, free or busy availability, public or private status, and categories or colours. Recurring items are synced as a series rather than expanded into separate events, and only changed attributes are updated on each pass.

Two constraints follow from the architecture rather than the feature list.

The first is platform. OGCS states its minimum requirement as any version of Windows with .NET Framework 4.5, and the version 2 line additionally requires a classic Outlook client. Version 3 is the line that connects to Microsoft 365 cloud accounts directly, which is what the New Outlook for Windows application needs. There is no macOS build, so a Mac only household cannot run this route at all.

The second is that a desktop program only syncs while it is running. The site notes the tool can sit in the system tray and start on login, and it offers configurable sync frequency including push from Outlook, but a laptop that is closed is a laptop that is not reconciling. Availability lookup and server side feeds have no such gap.

Corporate policy is the practical blocker more often than either. A program that authenticates to Exchange Web Services and reads full event bodies is exactly what a security team is watching for, even when the program itself requires no install and no local administrator privileges, as OGCS advertises.

Which route matches which situation

Route Layer What crosses Editable on both sides Who has to set it up
Calendar Interop Server to server Busy blocks, optionally titles and locations No Google Workspace administrator
iCalendar URL subscription Feed Full event fields from the published calendar No The individual user
Program based replication Client Subject, description, location, attendees, reminders, colours Yes The individual user, on Windows

Reading the table the other way round is the useful move. If the requirement is that nobody double books a shared room, the first row is enough and the other two add risk. If the requirement is reading a work agenda on a personal phone, the second row is enough and the third is overkill. Only a genuine need to create and edit the same event from either system justifies the third row, and that need is rarer than it feels.

Where duplicates and ghost events come from

Almost every duplicate event in this pairing traces to one of four causes.

Two routes running at once. A subscribed feed plus a replication program means the same meeting arrives twice by two different paths, with two different identifiers, so neither side recognises them as the same thing. Turning one off is the fix, and the feed is usually the one to drop.

Invitations treated as copies. When a meeting organiser on Exchange invites a Google address directly, Google Calendar already holds that event as an invitation. A replication program that also copies the Exchange original produces a second event at the same time. Most tools have a setting for which calendar folders to include, and narrowing that scope is more reliable than deduplicating afterwards.

Recurrence expanded instead of linked. A weekly meeting that crosses as 52 independent events will not follow a change to the series. This is why the series handling in a replication tool matters more than any other single feature.

Privacy flags misread as missing data. An event that shows as busy with no title is not a broken sync. With Calendar Interop that is the documented behaviour for an event marked private on the other system, and for availability only lookups it is the documented behaviour for every event. Chasing that as a bug wastes an afternoon.

Timezone handling deserves one line of its own. Both systems store timezone data, but an event created from a mobile client while travelling can carry a different timezone than expected, and a route that only moves start and end instants will show the shifted time without explaining why. Checking the timezone on the original event before blaming the sync is the faster order of operations.

What the Mac side can and cannot reach

A native Mac calendar changes what is comfortable here, but it does not change what the servers allow. A desktop calendar app that speaks to Google Calendar reaches Exchange only as far as one of the three routes above has already carried the data. If Exchange availability is not reaching Google Calendar, no client side app can conjure it.

What the client layer does change is everything that happens after the data arrives. Multiple Google accounts shown in one grid, saved combinations of visible calendars for work and personal contexts, subscribed iCalendar feeds overlaid as a separate layer, and meeting links detected across Zoom, Google Meet, Teams, and Webex so that joining is one click rather than a hunt through an event body. The Features page lists what a Mac client of this kind covers, and the Compared with other calendars page sets out how full featured Mac calendar apps line up on price over a three year window.

The practical sequence is therefore server first, client second. Get the Exchange side landing in Google Calendar by whichever of the three routes fits the constraint, confirm that a moved meeting actually moves, and only then decide which Mac client makes the combined view readable.

What to change first

Name the requirement before picking a route: availability only, read only visibility, or genuine two way editing. Then set up the single route that matches it and switch off any second route already running, because overlapping routes are the main source of duplicates. Once the data lands reliably, Caltimate or any other full featured Mac client can take over the reading and the daily planning.

Frequently asked questions

Can Exchange and Google Calendar sync without an administrator?

Not at the server level. Calendar Interop, the route both vendors support, is configured for a whole domain by a Google Workspace administrator and requires role accounts on both systems. Without administrator access the remaining options are an iCalendar URL subscription, which is read only, or a program on a Windows desktop that holds credentials for both calendars.

Why do subscribed calendar events show yesterday's times?

Subscribed feeds are pulled on a schedule, not pushed. Microsoft's documentation for Outlook.com and Outlook on the web says a subscribed calendar refreshes approximately every three hours and can sometimes take more than 24 hours. Any change made inside that window is invisible on the subscribing side until the next fetch.

Why does an Exchange meeting appear as busy with no title?

That is usually the documented behaviour rather than a fault. Calendar Interop shows only busy blocks for availability lookups, and it honours event level privacy, so an event marked private in Exchange does not expose its details to Google Calendar. The same rule applies in the other direction.

Is there a two way sync tool that runs on macOS?

The established open source option for this pairing, Outlook Google Calendar Sync, lists any version of Windows with .NET Framework 4.5 as its minimum requirement, so it does not run on macOS. A Mac can still show the combined result if the Exchange side reaches Google Calendar by another route first, because Mac calendar clients connect to Google Calendar rather than to Exchange directly.

What is the difference between importing and subscribing to a calendar file?

Importing takes a one time snapshot. Microsoft's documentation states that imported events do not refresh even when the calendar owner makes an update, which makes import suitable only for fixed schedules. Subscribing connects to the source URL and keeps fetching, so later changes arrive, subject to the refresh interval.

Back to all posts