System Design Masterclass
E-Commercecalendarschedulingcollaborationrecurring-eventstimezoneintermediate

Design Google Calendar

Design a calendar system with scheduling and collaboration

Billions of events|Similar to Google, Microsoft, Apple, Calendly, Zoom|45 min read

Summary

A calendar app helps you create events, set up meetings that repeat (like a daily standup or weekly team call), share your schedule with others, and get reminders before meetings start. The tricky parts are: handling events that repeat forever without storing millions of copies, showing the right time for people in different countries, making sure two meetings don't get booked at the same time, and keeping your calendar the same on your phone and computer. Companies like Google, Microsoft, and Apple ask this question in interviews.

Key Takeaways

Core Problem

The main job is to quickly find all events in a date range (like showing your week view) while letting multiple people share and edit calendars together.

The Hard Part

A daily meeting that repeats forever would need millions of rows in the database. Instead, we save the rule (repeat every day) and create the actual events only when someone looks at their calendar.

Scaling Axis

Each person's calendar is separate, so we can split the data by user. The slow part is when we need to check multiple people's calendars at once (like finding a time when everyone is free).

Critical Invariant

Never let someone book two meetings at the same time if they marked themselves as busy. Always check for conflicts before saving a new event.

Performance Requirement

The calendar page must open in less than half a second. This means we need fast searches and must save recently viewed dates so we don't recalculate them every time.

Key Tradeoff

We save space by storing just the repeat rule instead of every single event. This means more work when loading the calendar, but we use caching to make it fast.

Design Walkthrough

Problem Statement

The Question: Design a calendar app like Google Calendar where people can create events, set up repeating meetings, and share their schedule with others.

What the app needs to do (most important first):

  1. 1.Create and edit events - Users can add meetings with a title, time, and place. Events can be for a specific time (like 2pm-3pm) or all day (like a birthday).
  2. 2.Show the calendar - Display events in day, week, or month view so users can see their schedule at a glance.
  3. 3.Repeating events - Set up meetings that happen again and again (like a daily standup at 9am or a weekly team call every Monday).
  4. 4.Share and invite - Send meeting invites to others and let them say yes, no, or maybe. Share your whole calendar with teammates.
  5. 5.Reminders - Send notifications before a meeting starts (like 15 minutes before) through email, phone notification, or text.
  6. 6.Prevent double-booking - Warn users if they try to schedule two meetings at the same time.
  7. 7.Handle different time zones - Show the correct time for people in different countries (a 9am meeting in New York shows as 6am in San Francisco).

What to say first

Let me first understand what features we need to build. Should users be able to create repeating events? Do we need calendar sharing and meeting invites? Once I know the features, I will ask about scale - how many users and events we need to support.

What the interviewer really wants to see: - Can you handle repeating events without saving millions of copies in the database? - Do you know that time zones are tricky? (9am in New York is different from 9am in Tokyo) - Can you quickly find all events in a week without scanning the whole database? - How do you stop two people from booking the same meeting room at the same time?

Clarifying Questions

Before you start designing, ask questions to understand what you are building. Good questions show the interviewer you think before you code.

Question 1: How big is this?

How many people will use this calendar? How many events will they create? Do people look at their calendar more often than they create events?

Why ask this: If millions of people use it, we need a different design than if only a few thousand use it.

What interviewers usually say: 100 million users, 10 billion events total. People look at their calendar 50 times for every 1 event they create (this is called a read-heavy system).

How this changes your design: Since people look at calendars much more than they create events, we should make viewing fast (use caching) even if creating is a bit slower.

Question 2: How fancy are repeating events?

Do we just need simple repeating events (every day, every week) or complex ones (every 3rd Tuesday of the month, skip holidays)?

Why ask this: Complex repeating patterns are much harder to build.

What interviewers usually say: Support the common patterns (daily, weekly, monthly) plus the ability to skip or change one day in the series (like skipping a meeting during vacation).

How this changes your design: We need to store the repeat rule AND a list of exceptions (days that are different from the pattern).

Question 3: How fast should changes appear?

If I change a meeting on my computer, how quickly should it show up on my phone? Instantly, or is a few seconds okay?

Why ask this: Instant sync (under 1 second) needs special technology. A few seconds delay is much easier to build.

What interviewers usually say: A few seconds delay is fine.

How this changes your design: We can use simpler methods - the phone can check for updates every few seconds instead of needing a constant connection.

Question 4: Personal or shared calendars?

Is this just for personal calendars, or do teams share calendars? Do we need to book meeting rooms too?

Why ask this: Shared calendars need permissions (who can see what, who can edit).

What interviewers usually say: Personal calendars plus shared team calendars. Meeting room booking can be added later.

How this changes your design: We need to track who owns each calendar and who has permission to view or edit it.

Summarize your assumptions

Let me summarize what I will design for: 100 million users, 10 billion events, simple repeating patterns with exceptions, updates can take a few seconds to sync, and we need both personal and shared calendars. I will add meeting room booking as a future feature.

The Hard Part

Say this to the interviewer

The hardest part of a calendar is handling repeating events. Think about it: a daily standup meeting for 10 years means 3,650 meetings. We cannot save all 3,650 rows in the database - that would be wasteful. But when someone looks at their calendar, they need to see those meetings.

Why repeating events are tricky (explained simply):

  1. 1.They can go on forever - If someone creates a daily meeting with no end date, that is infinite meetings. You cannot store infinite rows in a database. 2. People skip some days - You have a weekly Monday meeting, but you are on vacation one Monday. Now that repeating event has a hole in it. 3. People change just one day - Your 9am standup is moved to 10am just for March 15th. The rest stay at 9am. One meeting in the series is different. 4. You need to show them quickly - When someone opens their calendar to see this week, you need to show all their repeating events instantly - you cannot make them wait. 5. Time zones change - Daylight saving time happens. A 9am meeting should still be at 9am after the clocks change, not 8am or 10am.

Common mistake candidates make

Many people say: just save every single meeting in the database when the user creates a repeating event. This is wrong because: (1) events with no end date would need infinite rows, (2) it wastes huge amounts of storage, (3) changing the whole series means updating thousands of rows.

Two ways to handle repeating events:

Option 1: Save the rule, calculate when needed (Recommended) - Save just the pattern: repeat every Monday at 9am - When someone looks at March, calculate which Mondays are in March and show those - Save exceptions separately (the vacation day you skipped) - Why this is better: Uses very little storage, handles forever-repeating events, easy to change the whole series

Option 2: Save all the meetings ahead of time - When user creates a repeating event, immediately create the next 2 years of meetings in the database - A background job adds more meetings as time passes - Why this is worse: Uses lots of storage, needs background jobs to keep up, cannot handle events with no end date

How we show repeating events

Scale and Access Patterns

Before designing, let me figure out how big this system needs to be. This helps us choose the right tools.

What we are measuringNumberWhat this means for our design
Total users100 millionOne database handles this fine - no sharding needed yet
Events per personAbout 10010 billion events total = about 7 TB storage (PostgreSQL handles 50+ TB easily)
+ 5 more rows...

What to tell the interviewer

At 100 million users, a single PostgreSQL database with read replicas handles this scale comfortably. We do NOT need sharding for capacity - 10 billion events (7 TB) and 115 writes/second are well within PostgreSQL limits. Our focus should be: (1) Redis caching for the 50:1 read-heavy pattern, (2) good indexes for date-range queries, (3) read replicas to spread the load.

Common interview mistake: Over-engineering with sharding

Many candidates jump to sharding too early. Interviewers will ask: Why do you need to shard? At 100M users, the honest answer is: We probably do not need it yet. Sharding adds complexity (cross-shard queries for find-a-time become slow) and should only be considered at 1 billion+ users, or for data residency laws (EU data must stay in EU). Do not add complexity you do not need.

How people use the calendar (from most common to least common):

  1. 1.View their calendar - Someone opens the app to see their week or month. This is the #1 thing people do, so it must be fast.
  2. 2.Find a time to meet - Check when multiple people are free. This is slower because we need to check several calendars.
  3. 3.Look at one event - Click on a meeting to see details like location and attendees.
  4. 4.Get reminders - The system checks for upcoming meetings and sends notifications.
How much space does one event need?
- Event info (title, time, location): about 500 bytes
- Repeat rule (if it repeats): about 200 bytes more
+ 12 more lines...

High-Level Architecture

Now let me draw the big picture of how all the pieces fit together. I will keep it simple and explain what each part does.

What to tell the interviewer

I will break this into separate services - one for calendar events, one for handling repeating events, one for sending reminders, and one for search. Each service does one job well. We split data by user so each person's calendar is independent.

Calendar System - The Big Picture

What each service does and WHY it is separate:

ServiceWhat it doesWhy it is separate (what to tell interviewer)
Calendar ServiceCreates, reads, updates, deletes events. Checks permissions.This is the main service. It handles simple CRUD operations and stays fast because complex work is delegated to other services.
Recurrence ServiceCalculates actual dates from repeat rules like every Monday. Handles exceptions (skipped days).Why separate? Calculating repeating events is CPU-intensive. If we did it in the main service, one user with complex repeat rules could slow down everyone. Separate service means we can scale it independently and cache results.
Notification ServiceSends reminders via email, push notification, or SMS.Why separate? Sending notifications is slow (waiting for email servers, push services). We do not want users waiting for a reminder to be scheduled before they can save their event. Also, notification failures should not affect calendar operations.
Search ServiceFinds events by keyword (all meetings about budget).Why separate? Search needs a special database (Elasticsearch) that is different from our main database. Indexing is slow and should happen in the background. Users should not wait for search index to update before their event saves.

Common interview question: Why not one big service?

Interviewers often ask: Why do you need separate services? Can't the Calendar Service do everything? Your answer: Yes, for a small app with few users, one service works fine. We split into services when: (1) different parts need to scale differently - notifications spike before meetings, (2) different parts have different failure modes - email being down should not break calendar viewing, (3) different parts need different technologies - search needs Elasticsearch, main data needs PostgreSQL.

Technology Choices - Why we picked these tools:

Database: PostgreSQL (Recommended) - Why we chose it: Great at finding events in a date range (show me this week), handles relationships well (events belong to calendars), most engineers know SQL - Other options we considered: - MySQL: Also works great - pick this if your team knows it better - MongoDB: Not ideal because calendar data has lots of relationships - DynamoDB: Scales well but harder to query date ranges

Cache: Redis (Recommended) - Why we chose it: Super fast, can automatically delete old data, everyone uses it so lots of help available - Other options we considered: - Memcached: Simpler but Redis has more features we need - In-memory cache: Only works for small systems with one server

Message Queue: Kafka or RabbitMQ - Why we need it: Some tasks can wait (like updating search index). We put them in a queue and do them later. - Kafka: Better if you need to replay old messages - RabbitMQ: Simpler to set up and use

Search: Elasticsearch - Why we chose it: Built specifically for searching text, very fast, handles millions of events

Important interview tip

Pick technologies YOU know! If you have used MySQL at your job, use MySQL in your design. If you know MongoDB well, explain why it could work here. Interviewers care more about your reasoning than the specific tool. Say something like: I will use PostgreSQL because I have experience with it, but MySQL would work just as well.

How real companies do it

Google Calendar uses Spanner (their special global database). Microsoft Outlook uses Exchange Server. But for most companies, PostgreSQL with Redis caching works perfectly fine up to 100 million users.

Data Model and Storage

Now let me show how we organize the data in the database. Think of tables like spreadsheets - each one stores a different type of information.

What to tell the interviewer

I will use a SQL database with three main tables: calendars (the containers), events (the meetings), and attendees (who is invited). I will add indexes to make searching by date fast. For repeating events, I save the rule like every Monday instead of every single meeting.

Table 1: Calendars - Think of this as a folder that holds events

Each person can have multiple calendars (Work, Personal, Family). This table stores: - Who owns the calendar - The calendar name and color - What timezone the owner is in - Which calendar is the main one

ColumnWhat it storesExample
idUnique ID for this calendarcal_abc123
owner_idWho owns this calendaruser_456
+ 5 more rows...

Table 2: Events - The actual meetings and appointments

This stores both one-time events AND the rules for repeating events. Key fields: - What calendar it belongs to - Title, description, location - Start and end time (always saved in UTC - one universal time) - For repeating events: the repeat rule (like every Monday)

ColumnWhat it storesExample
idUnique ID for this eventevt_789
calendar_idWhich calendar this belongs tocal_abc123
+ 12 more rows...

Database Index

We add an INDEX on (calendar_id, start_time, end_time). This makes finding events by date FAST - like a book's index that helps you find pages quickly.

Table 3: Exceptions - When one day in a repeating series is different

If you have a weekly Monday meeting but skip one Monday (vacation), we save that skip here. Or if you moved just one meeting to Tuesday, we save that change here.

ColumnWhat it storesExample
idUnique IDexc_111
recurring_event_idWhich repeating event this changesevt_789
+ 7 more rows...

Table 4: Attendees - Who is invited to each meeting

When you invite people to a meeting, we save who is invited and whether they said yes, no, or maybe.

ColumnWhat it storesExample
idUnique IDatt_222
event_idWhich meetingevt_789
+ 8 more rows...

Database Index

We add an INDEX on (user_id, event_id). This lets us quickly find all meetings a person is invited to.

Important: How we handle time zones

Always save times in UTC (one universal time used worldwide) in the database. Save the user's timezone separately. Why? A 9am meeting in New York should show as 9am to someone in New York, but the database stores it as 2pm UTC. When daylight saving happens, the UTC time changes but the local time (9am) stays the same.

Recurring Event Deep Dive

Let me explain step by step how we turn a repeat rule into actual meetings on the calendar.

How we write repeat rules (called RRULE - a standard format):

Think of it like writing instructions for a robot:

What you wantHow we write itWhat it means
Every dayFREQ=DAILYRepeat once a day
Every Monday, Wednesday, FridayFREQ=WEEKLY;BYDAY=MO,WE,FRWeekly on these days
+ 5 more rows...

Step by step: How we show repeating events

When someone opens their March calendar, here is what happens:

  1. 1.Get the repeat rule - Load Team Standup: every weekday at 9am from the database 2. Calculate the dates - Figure out which weekdays are in March (March 3, 4, 5, 6, 7, 10, 11... etc) 3. Check for exceptions - Load any skipped or changed days (oh, March 14 was skipped - vacation day) 4. Remove the skipped days - Take March 14 out of the list 5. Apply changes - March 21 was moved to 10am instead of 9am - update that one 6. Return the final list - Send back all the meetings to show on the calendar
FUNCTION expand_recurring_event(event, view_start_date, view_end_date):
    
    // Example: event has rule "every Monday at 9am"
+ 31 more lines...

Making it fast with caching

Calculating all these dates takes time. If 1000 people open their March calendar at the same time, we do not want to calculate 1000 times. Instead:

  1. 1.First person asks for March events 2. We calculate and save the result in Redis (fast temporary storage) 3. Next 999 people get the saved result instantly 4. After 5 minutes, we delete the saved result (in case something changed)
FUNCTION get_events_in_range(calendar_id, start_date, end_date):
    
    // Create a unique name for this request
+ 32 more lines...

When to delete the cache

Whenever someone creates, edits, or deletes an event in a calendar, we delete all cached results for that calendar. This way, the next person who looks will see the updated events. Simple rule: any change to a calendar = delete that calendar's cache.

Preventing Double Booking

The golden rule

Never let someone accidentally book two meetings at the same time. For meeting rooms, if two people try to book the same room at the same time, only one should succeed - the other should get an error.

How do we know if two meetings overlap?

Two meetings conflict if one starts before the other ends. Think about it: - Meeting A: 2pm to 3pm - Meeting B: 2:30pm to 3:30pm - They overlap because A starts (2pm) before B ends (3:30pm) AND B starts (2:30pm) before A ends (3pm)

The simple rule: Two events overlap if event1.start < event2.end AND event1.end > event2.start

FUNCTION check_for_conflicts(user_id, new_start_time, new_end_time):
    
    // Before creating a new meeting, check if it conflicts with existing ones
+ 16 more lines...

The tricky problem: Two people booking at the same instant

Imagine this: Two people click Book Room at the exact same second for the same conference room. Both check if the room is free - it is! Both try to book it. Without protection, both bookings would succeed and we have a mess.

The solution is called a transaction - we tell the database: Check if it is free AND book it as one single action that cannot be interrupted.

FUNCTION create_event_safely(event_data, user_id):
    // Create an event, but first check for conflicts.
    // Uses a transaction so check + create happen together safely.
+ 44 more lines...

Personal calendars vs meeting rooms - different rules

For personal calendars, we usually just show a warning - Hey, you already have a meeting then. Users might intentionally double-book (they will skip one). For meeting rooms and equipment, we strictly prevent double-booking because two teams cannot use the same room at the same time.

What Can Go Wrong and How We Handle It

Tell the interviewer about failures

Good engineers think about what can break. Let me walk through the things that can go wrong and how we protect against them.

Common failures and how we handle them:

What breaksWhat happens to usersHow we fix itWhy this works
Database goes downCannot see or create eventsKeep backup database copies + use cached dataUsers can still see recent calendar data from cache
Too many people hit empty cache at onceDatabase gets overwhelmed with requestsOnly let one request fetch data, others wait for that resultInstead of 1000 database queries, we do just 1
+ 4 more rows...

Making sure reminders never get lost

Reminders are super important - if someone misses a reminder, they might miss their meeting! Here is how we make sure reminders always get sent:

  1. 1.Primary system: When you create an event, we schedule the reminder in a job queue 2. Backup system: We also save the reminder in a database table 3. Safety check: A background job runs every minute looking for reminders that should have been sent but were not

This way, even if the primary system fails, the backup catches it.

FUNCTION schedule_reminders(event):
    // Schedule reminders with a backup system.
    
+ 31 more lines...

What is idempotent? (important word to know)

Idempotent means: doing something twice has the same result as doing it once. For reminders, we use a unique ID (event + time) so even if we accidentally try to send twice, only one reminder goes out. Sending a duplicate reminder is annoying but not terrible - missing a reminder is much worse!

Growing the System Over Time

What to tell the interviewer

This design works great for up to 100 million users in one location. Let me explain how we would grow it if we need to support users around the world or add more features.

How we grow step by step:

Stage 1: Starting out (up to 100 million users) - One PostgreSQL database with read replicas - Redis for caching (90%+ cache hit rate) - All servers in one region (like US-East) - This handles 10 billion events, 7 TB storage, 5000+ reads/second easily - Most companies never need to go beyond this stage

Stage 2: Global users (100-500 million users across continents) - Add read replicas in multiple regions (US, Europe, Asia) - Users read from the closest replica for low latency - All writes still go to one primary database - This is replication, NOT sharding - much simpler

Stage 3: Massive scale (1 billion+ users, like Google) - Consider sharding only if you truly need it - Or use globally distributed databases (like Google Spanner, CockroachDB) - Warning: Sharding makes find-a-time queries much harder - Only do this for capacity OR for data residency laws

Servers in multiple locations

Cool features we can add later:

1. Find a time when everyone is free

When you want to schedule a meeting with 5 people, the app can check everyone's calendar and suggest times when all 5 are available.

FUNCTION find_times_when_everyone_is_free(people, meeting_length, date_range):
    // Look at everyone's calendar and find open slots.
    // Example: Find a 1-hour slot next week when Alice, Bob, and Carol are all free.
+ 25 more lines...

2. Working hours and out of office - Save what hours each person works (like 9am-5pm Monday-Friday) - Automatically say no to meetings outside those hours - Set up auto-replies when you are on vacation

3. Calendar statistics - Show how many hours you spent in meetings this week - Suggest times to block for focused work - Warn if you have too many meetings

What about multiple people editing the same event?

If two people try to edit the same meeting at exactly the same time (rare for calendars), we use a simple rule: the last save wins. We could add fancier technology (like Google Docs uses for real-time editing) but calendars rarely need it - usually only one person edits an event at a time.

Different types of calendar apps need different focus:

Meeting room booking system: Focus on preventing double-booking and maybe add a waitlist for popular rooms.

Enterprise calendar (like Outlook): Need to connect with company systems, let assistants manage boss's calendar, and handle complex company hierarchies.

Scheduling tool (like Calendly): Focus on sharing available times with people outside your company, letting them book appointments, and maybe taking payments.

Design Trade-offs

Advantages

  • +Easy to search - all meetings are already there
  • +No calculation needed when showing calendar
  • +Simple to check for conflicts

Disadvantages

  • -Uses tons of storage (daily meeting for 10 years = 3,650 rows)
  • -Cannot handle meetings that repeat forever
  • -Changing the whole series means updating thousands of rows
When to use

Not recommended for real calendars. Only use for temporary caching (like pre-calculating next 30 days).