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.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.Show the calendar - Display events in day, week, or month view so users can see their schedule at a glance.
- 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.Share and invite - Send meeting invites to others and let them say yes, no, or maybe. Share your whole calendar with teammates.
- 5.Reminders - Send notifications before a meeting starts (like 15 minutes before) through email, phone notification, or text.
- 6.Prevent double-booking - Warn users if they try to schedule two meetings at the same time.
- 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.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 measuring | Number | What this means for our design |
|---|---|---|
| Total users | 100 million | One database handles this fine - no sharding needed yet |
| Events per person | About 100 | 10 billion events total = about 7 TB storage (PostgreSQL handles 50+ TB easily) |
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.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.Find a time to meet - Check when multiple people are free. This is slower because we need to check several calendars.
- 3.Look at one event - Click on a meeting to see details like location and attendees.
- 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 moreHigh-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:
| Service | What it does | Why it is separate (what to tell interviewer) |
|---|---|---|
| Calendar Service | Creates, 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 Service | Calculates 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 Service | Sends 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 Service | Finds 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
| Column | What it stores | Example |
|---|---|---|
| id | Unique ID for this calendar | cal_abc123 |
| owner_id | Who owns this calendar | user_456 |
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)
| Column | What it stores | Example |
|---|---|---|
| id | Unique ID for this event | evt_789 |
| calendar_id | Which calendar this belongs to | cal_abc123 |
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.
| Column | What it stores | Example |
|---|---|---|
| id | Unique ID | exc_111 |
| recurring_event_id | Which repeating event this changes | evt_789 |
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.
| Column | What it stores | Example |
|---|---|---|
| id | Unique ID | att_222 |
| event_id | Which meeting | evt_789 |
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 want | How we write it | What it means |
|---|---|---|
| Every day | FREQ=DAILY | Repeat once a day |
| Every Monday, Wednesday, Friday | FREQ=WEEKLY;BYDAY=MO,WE,FR | Weekly on these days |
Step by step: How we show repeating events
When someone opens their March calendar, here is what happens:
- 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"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.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 requestWhen 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 onesThe 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.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 breaks | What happens to users | How we fix it | Why this works |
|---|---|---|---|
| Database goes down | Cannot see or create events | Keep backup database copies + use cached data | Users can still see recent calendar data from cache |
| Too many people hit empty cache at once | Database gets overwhelmed with requests | Only let one request fetch data, others wait for that result | Instead of 1000 database queries, we do just 1 |
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.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.
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.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.