Its primitive API enables scheduling for the internet, and its client is a masterpiece of restraint. How Google Calendar works, and what we can learn from it as engineers. Architecture Frontend framework: None (!). Just a few in-house libraries for things like authentication and shared utils. Frontend framework Frontend Styling: CSS classnames, invoked by JS. Frontend Styling Frontend Storage: Cache Storage, IndexedDB (offline mode), CDN (images & fonts). Frontend Storage API Storage: Spanner DB. API Storage External APIs: Google Meet, Google Contacts, Google Auth. External APIs Services: heartbeat, eventing, notifications. Services Other: An in-house compiler that makes JS download and run faster. Other Interesting Problems Sure, a calendar is one big CRUD app. But don’t let that fool you — there were plenty of demanding technical problems that had to be solved. Calendar API REST+JSON since 2011 (originally REST+RSS-style feed) Data model leans heavily on RFC 5545 iCalendar recurrence strings (Microsoft & Apple use proprietary objects) Clients can watch/subscribe to receive a webhook notification when events change Supports incremental syncs for speed…but also requires you to handle expirations & re-syncs on your own Uses quotas & rate limits to reduce performance issues Powerful yet primitive. They’ll give you enough to do whatever you need to, but they won’t figure it out for you. REST+JSON since 2011 (originally REST+RSS-style feed) REST+JSON Data model leans heavily on RFC 5545 iCalendar recurrence strings (Microsoft & Apple use proprietary objects) Data model Clients can watch/subscribe to receive a webhook notification when events change watch/subscribe Supports incremental syncs for speed…but also requires you to handle expirations & re-syncs on your own incremental syncs Uses quotas & rate limits to reduce performance issues quotas & rate limits Powerful yet primitive. They’ll give you enough to do whatever you need to, but they won’t figure it out for you. Powerful yet primitive HTML layout Yes, structuring HTML can actually be interesting! Since the calendar views are rich with content, big performance issues occur if elements aren’t isolated. big performance issues occur Here are the most important HTML layers: The grid: all-day row, day columns, timed events, container The preview event, which can’t be locked to a row/column The drag layer. This allows you to DND tasks to the grid Forms: floating next to events on the grid and expanded into a full-screen dialog Toasts: For confirmation messages The grid: all-day row, day columns, timed events, container The grid The preview event, which can’t be locked to a row/column The preview event The drag layer. This allows you to DND tasks to the grid The drag layer Forms: floating next to events on the grid and expanded into a full-screen dialog Forms Toasts: For confirmation messages Toasts Frontend Algorithms Each calendar client has a few juicy algorithms Event position: the length, height, and coordinates (X, Y) of each event div. To compute this, you need to account for the event duration and view scale. All-day event lengths: The width and Y coordinates, which need to be adjusted based on the surrounding events. Overlapping events: how to adjust events when they share times. Gcal’s implementation is more sophisticated compared to Outlook’s (which halves each event). Pseudo-code below. // overlapping events logic if start or end of targetEvent overlaps with any(events): if start and end of targetEvent = start and end of any(events): orderEventsAlphabeticallyByTitle() if start of targetEvent = start of any(events) and end != end of any(events): orderByDuration() //longest events go behind shorter events if start or end of targetEvent != start or end of any(events): if targetEvent overlaps multiple events: targetEventGoesInFrontOfEvents() else: orderEventsByStart() //events that start earlier go behind Event position: the length, height, and coordinates (X, Y) of each event div. To compute this, you need to account for the event duration and view scale. Event position: the length, height, and coordinates (X, Y) of each event div. To compute this, you need to account for the event duration and view scale. Event position All-day event lengths: The width and Y coordinates, which need to be adjusted based on the surrounding events. All-day event lengths: The width and Y coordinates, which need to be adjusted based on the surrounding events. All-day event lengths Overlapping events: how to adjust events when they share times. Gcal’s implementation is more sophisticated compared to Outlook’s (which halves each event). Pseudo-code below. // overlapping events logic if start or end of targetEvent overlaps with any(events): if start and end of targetEvent = start and end of any(events): orderEventsAlphabeticallyByTitle() if start of targetEvent = start of any(events) and end != end of any(events): orderByDuration() //longest events go behind shorter events if start or end of targetEvent != start or end of any(events): if targetEvent overlaps multiple events: targetEventGoesInFrontOfEvents() else: orderEventsByStart() //events that start earlier go behind Overlapping events: how to adjust events when they share times. Gcal’s implementation is more sophisticated compared to Outlook’s (which halves each event). Pseudo-code below. Overlapping events // overlapping events logic if start or end of targetEvent overlaps with any(events): if start and end of targetEvent = start and end of any(events): orderEventsAlphabeticallyByTitle() if start of targetEvent = start of any(events) and end != end of any(events): orderByDuration() //longest events go behind shorter events if start or end of targetEvent != start or end of any(events): if targetEvent overlaps multiple events: targetEventGoesInFrontOfEvents() else: orderEventsByStart() //events that start earlier go behind // overlapping events logic if start or end of targetEvent overlaps with any(events): if start and end of targetEvent = start and end of any(events): orderEventsAlphabeticallyByTitle() if start of targetEvent = start of any(events) and end != end of any(events): orderByDuration() //longest events go behind shorter events if start or end of targetEvent != start or end of any(events): if targetEvent overlaps multiple events: targetEventGoesInFrontOfEvents() else: orderEventsByStart() //events that start earlier go behind See the Compass repo for our full implementation of these algos. the Compass repo Services These are the external workhorses that allow the client code to stay simple and reliable Heartbeat service — Allows GCal to be reliable and fall back to offline mode gracefully Eventing service — pub/sub style events that power the webhooks for clients. This allows other apps to build upon the GCal API. Notifications service — coordinating the timing of your pre-event notifications. The client could do this alone in theory, but it would be less reliable. Heartbeat service — Allows GCal to be reliable and fall back to offline mode gracefully Heartbeat Eventing service — pub/sub style events that power the webhooks for clients. This allows other apps to build upon the GCal API. Eventing Notifications service — coordinating the timing of your pre-event notifications. The client could do this alone in theory, but it would be less reliable. Notifications [ Takeaways Building a global-scale CRUD app might look straightforward from the architecture diagram, but that simplicity still demands a high level of execution. API reliability: Since so many apps rely on two-way syncing with a user’s GCal, the API needs to be simple, extensible, and reliable. If they mess up, they break an army of other apps downstream. Data security: Calendar data is extremely sensitive. They rely heavily on scope-based roles to ensure that only the people/apps you authorize can access your data. Monitoring services: Health checks, logging, and syncing are happening non-stop behind the scenes. API reliability: Since so many apps rely on two-way syncing with a user’s GCal, the API needs to be simple, extensible, and reliable. If they mess up, they break an army of other apps downstream. API reliability Data security: Calendar data is extremely sensitive. They rely heavily on scope-based roles to ensure that only the people/apps you authorize can access your data. Data security Monitoring services: Health checks, logging, and syncing are happening non-stop behind the scenes. Monitoring services Given the scale demands, you can make life easier for yourself by simply not doing things. not doing things not doing things You don’t need to use the trending stack. Imagine if they dropped everything to rewrite their app in Angular. Then React. Then Svelete. Then NextJS. Then HTMX. All of those came after Google Calendar shipped. GCal picked JS, pulled over to the right lane, and has been coasting at 64MPH for decades. No one cares. You don’t need to publish on every platform. Pull up the Google Calendar desktop app right now. I’ll wait. You don’t need to keep up with the styling trends. Bootstrap. Bulma. styled-components. Tailwind. CSS class names. You don’t need to have the best UX. Dark mode. Forms that conserve space. #FFFFFF light mode. Full-page forms. You don’t need to have the best performance. Their lighthouse score on Performance is 31/100. You don’t need to use the trending stack. Imagine if they dropped everything to rewrite their app in Angular. Then React. Then Svelete. Then NextJS. Then HTMX. All of those came after Google Calendar shipped. GCal picked JS, pulled over to the right lane, and has been coasting at 64MPH for decades. No one cares. You don’t need to use the trending stack You don’t need to publish on every platform. Pull up the Google Calendar desktop app right now. I’ll wait. You don’t need to publish on every platform You don’t need to keep up with the styling trends. Bootstrap. Bulma. styled-components. Tailwind. CSS class names. You don’t need to keep up with the styling trends You don’t need to have the best UX. Dark mode. Forms that conserve space. #FFFFFF light mode. Full-page forms. You don’t need to have the best UX You don’t need to have the best performance. Their lighthouse score on Performance is 31/100. You don’t need to have the best performance Much like in life, it pays to know thyself when shipping product. Google Calendar isn’t trying to be the modern app that executive assistants use to schedule 40 meetings a day (That’s what Vimcal is for). Google Calendar aims to be a simple app that any one of its 2 billion users can operate without hand-holding. It scores 88/100 on accessibility. The UI doesn’t change. It doesn’t go down, and it has offline support if it does. It just works. That’s plenty. To get these deep dives in your inbox, subscribe to my newsletter, Fullstack Engineer. Fullstack Engineer