</> MAANG.io

Expert

Design landmark systems in depth, from Dynamo, GFS, Bigtable and Kafka to payments and ads pipelines.

0 of 232 solved 0%

Section 10: When Is Everyone Free? - Deep Dive: Free/Busy, Find-a-Time & Room Booking

Executive Summary: Free/busy reuses the per-calendar index and expand-on-read path from Sections 5 and 7 and returns busy intervals only, never titles. Find-a-time unions them with a sweep line, intersects the gaps with working hours and ranks 30-minute slots: about 21K calendar-window reads/s at peak, inside p99 ≤ 500 ms. Room booking is the correctness island: a conditional write in the room's own partition, run as a saga step after the event commits. That partition is the lock, so a room is accepted or declined within p99 ≤ 2 s and never double-booked. Only the room finder gets a materialized bitmap.

The interviewer turns to a fresh page: "Priya wants 30 minutes this week with her five direct reports. That's six calendars. Then she wants NYC-12-Hudson for Platform Sync. Walk me through both, and tell me what each one is allowed to see."

You: "Two problems share one screen. Find-a-time is a read that must be private and fast. Room booking is a write that must be correct. Separate machinery."

Free/Busy: A Read of the Index You Already Have

For each of the six calendars, the Free/Busy Service runs the same query as a week view. It range-scans single events in the window, scans the roughly 20 active series, expands them in their own IANA zones, and applies overrides. Then it filters. Accepted and tentative events count as busy. Declined events and events marked free (transparent) don't count. What comes out is a list of [start_utc, end_utc) intervals and nothing else.

Find-a-time pipeline: a request for 6 calendars, 30 min, this week passes an ACL check (freeBusyReader or better), then a per-calendar index scan and expand produces busy intervals (accepted and tentative, also served by the calendar-week cache on a hit with the same change-log seq), which a sweep-line union turns into free gaps, intersected with each person's working hours in their own zone to give 30-minute candidate slots and finally ranked suggestions.

The merge is a sweep line. Sort every interval endpoint, walk them in order, and keep a count of how many calendars are busy. Wherever the count is zero, everyone is free. Working hours are stored as local times in each person's zone, so the service converts them to UTC per day before intersecting. Take a report in Lisbon working 09:00–17:00 during the week of 26 Oct. Europe has already fallen back but the US hasn't, so that window is 05:00–13:00 New York time, and it overlaps Priya's day only from 09:00 to 13:00. Each gap is cut into 30-minute slots, and the slots are ranked: earliest first, then away from the edge of anyone's day.

Cost, from the ledger: 3.5K/s peak queries × 6 calendars ≈ 21K calendar-window reads/s, each well under 1 ms of expansion CPU. A short-TTL cache per calendar-week, keyed by the calendar's change-log seq, absorbs repeat lookups as Priya drags a slot around.

Interviewer: "Why not keep a busy bitmap for every user, always up to date?"

You: "Every edit on a billion calendars would pay to update it, for a query that's about 1% of reads. The flip trigger is a few calendars queried constantly. That's rooms, and I'll come back to them."

Quick check before moving on:

Sign in to continue reading

The rest of this lesson is available with a free account. Signing in with Google or Microsoft is free.

Sign in to read the full lesson

Sign in to MAANG.io

Use your Google or Microsoft account — no password to remember.

Continue with Google Continue with Microsoft

Please accept the terms above to continue.