Back to blog
Technical5 min read

How Calendar Sync Actually Works

A technical look at how MochiMeet keeps your availability accurate in real-time.

The Challenge

Calendar sync sounds simple: read events from your calendar, show available slots, done. In practice, it's surprisingly complex.

Here's what we're actually solving:

  • Multiple calendars (work, personal, side projects)
  • Different calendar providers (Google, Microsoft, Apple)
  • Timezone handling across the globe
  • Real-time updates as events change
  • Privacy (not exposing event details)
  • How MochiMeet Handles It

    Step 1: OAuth Connection

    When you connect your Google or Microsoft account, we request specific scopes:

  • Read access to your calendars (for busy times)
  • Write access to create events (for bookings)
  • We never see event titles or descriptions—just the time blocks that are busy.

    Step 2: Availability Calculation

    When someone visits your booking page, we:

  • Fetch busy intervals from all your connected calendars
  • Apply your weekly schedule (e.g., Mon-Fri 9am-5pm)
  • Apply booking rules (min advance, max advance, buffer times)
  • Generate available slots based on your increment setting
  • This all happens in real-time, every time someone loads your page.

    Step 3: Conflict Prevention

    Between loading slots and confirming a booking, things can change. Someone might book a slot on your calendar directly.

    We handle this with a double-check at booking time:

  • Re-fetch busy times
  • Verify the selected slot is still available
  • Only then create the calendar event
  • Timezone Magic

    Timezones are notoriously tricky. Here's our approach:

  • Your schedule is stored in your configured timezone
  • Busy times are fetched and compared in UTC
  • Slots are displayed in the guest's detected timezone
  • The booking record stores both timezones for clarity
  • This ensures a guest in Tokyo sees the correct times when booking with a host in New York.

    The Provider Abstraction

    Internally, we use a `CalendarProvider` interface:

    interface CalendarProvider {

    listCalendars(): Promise<Calendar[]>

    getBusyIntervals(start: Date, end: Date): Promise<Interval[]>

    createEvent(event: EventInput): Promise<Event>

    }

    This abstraction lets us support Google, Microsoft, and potentially other providers with consistent behavior.

    What's Next

    We're working on:

  • Webhook-based real-time sync (instead of polling)
  • iCal feed support for read-only calendars
  • Team calendar pooling for group availability

  • Questions about how something works? [Reach out](/support)—we love nerding out about this stuff.