Section 6: One Write, Many Calendars - High-Level Architecture
Executive Summary: This section puts boxes around Section 5's data model. A stateless Calendar Service writes to a Spanner-class store partitioned by calendar_id. Every commit includes an outbox row, and a change stream carries those rows to independent consumers: fan-out (which triggers the notifications), room booking, reminders and search. We trace Platform Sync from Priya's POST (acknowledged within 300 ms at p99) to Tomás's phone (updated within 5 s at p99). Then we walk the read path, defend the missing week-view cache, reject dual writes, and show why a cross-continent invite is just another async hop.
The interviewer slides the marker over: "You have a contract and a data model. Draw me the system." The weak move is to draw twelve boxes and narrate them left to right. The strong move is to say the organizing idea first.
You: "A write commits in exactly one place, and everything else follows. Priya's edit is durable once it's in her calendar's partition, together with an outbox row. Tomás's copy, Ana's copy, the tickles, the room booking and the reminders are all consumers of that commit. That's how the write stays at 300 ms while the fan-out behind it runs at about 104K calendar writes per second at peak."
The Whole System on One Whiteboard
| Component | Job | What breaks without it |
|---|---|---|
| Clients | Mobile keeps a local store and expands RRULEs itself. The device is the primary cache | Every glance at "what's next" needs a round trip, and nothing works offline |
| Edge / API Gateway | TLS, auth, rate limits, kill-switch by client version | Abuse and buggy clients reach the core |
| Calendar Service | Stateless. Validates, checks ACLs (cached with group memberships), expands, writes | Losing one instance breaks nothing (stateless); without the tier, every client would need ACL logic and an RRULE engine |
| Calendar Store | Spanner-class, partitioned by calendar_id, ~4.4 PB over 10 years |
Concurrent edits and RSVPs silently lose data |
| Change Stream | Kafka or Pub/Sub, partitioned by calendar_id, fed by the outbox |
Each consumer needs its own fragile hook into the write path |
| Fan-out Service | Writes guest copies and change-log entries, after the organizer commits | Every week view scatter-gathers across organizers |
| Notification Service | Content-free FCM/APNs tickles, sent only after a guest's copy commits; iMIP email for external guests | Devices fall back to polling |
| Resource Booking Service | Room saga: conditional write in the room's partition | NYC-12-Hudson gets double-booked |
| Reminder Horizon + Timer | 48 h time-bucketed store, ~600K/s burst sends | 16M reminders a minute hammer a database index |
| Free/Busy Service | Busy intervals only, no titles | Scheduling requires read access to everything |
| Search Indexer | Per-user event search | Search scans the serving store |
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